String
is a type:
type String = [Char]
Num
is a class:
class Num a where
(+), (-), (*) :: a -> a -> a
negate :: a -> a
abs :: a -> a
signum :: a -> a
fromInteger :: Integer -> a
negate x = 0 - x
Constraints only involve classes, not types.
Your ltest'
has a type parameter, a
.1 This can be expressed explicitly:
ltest' :: forall a. (Num a) => a -> a
This means it works with any type a
that has an instance of the Num
class.
Your test'
doesn't need type parameters, because it only works with one type2 (the argument can only be of type String
). So it also doesn't need any constraints, because there are no type parameters to constrain.
test' :: String -> String
test' a = a ++ " good job"
1 In other words, ltest'
has a polymorphic type.
2 In other words, test'
has a monomorphic type.