Sure, but typeclasses don’t help with that.
Here’s the same function in Haskell, using the
mult :: Num a => a -> Float -> Float mult a b = a * b
ghc says about it:
Mult.hs:2:16: error: • Couldn't match expected type ‘a’ with actual type ‘Float’ ‘a’ is a rigid type variable bound by the type signature for: mult :: forall a. Num a => a -> Float -> Float at Mult.hs:1:1-36 • In the second argument of ‘(*)’, namely ‘b’ In the expression: a * b In an equation for ‘mult’: mult a b = a * b • Relevant bindings include a :: a (bound at Mult.hs:2:6) mult :: a -> Float -> Float (bound at Mult.hs:2:1) | 2 | mult a b = a * b | ^
So going back to the original question:
This affects both Haskell and Elm equally, regardless of typeclasses, because both languages use Hindley-Milner type unification rather than subtyping.
Type unification lets you take a
number -> number -> number (in Elm) or
Num a => a -> a -> a (in Haskell) function and apply it with a
Float for either argument, but it still considers a
number -> Float -> Float function type-incompatible with a
number -> number -> number one (and likewise, it considers a
Num a => a -> Float -> Float function type-incompatible with
Num a => a -> a -> a). Subtyping could change that, but allowing subtyping would seriously degrade compile times in either language.
Typeclasses don’t help here!