Polymorphism, means "ploy" and "morphi", which is "many shapes". It is also known as "type scheme". A value is polymorphic if there is more than one type it can have.
Parameteric Polymorphism: parametric polymorphism refers to when the type of a value contains one or more (unconstrained) type variables, so that the value may adopt any type that results from substituting those variables with concrete types.
length :: [a] -> Int fst :: (a, b) -> a snd :: (a, b) -> b length :: forall a. [a] -> Int fst :: forall a b. (a, b) -> a
In Haskell, type variables always begin in lowercase whereas concrete types like
Stringalways start with an uppercase letter.
Also note, in languages like Haskell, functions are values of some function types.
Ad-hoc Polymorphism: ad-hoc polymorphism refers to when a value is able to adopt any one of several types because it, or a value it uses, has been given a separate definition for each of those types.
-- type 'a' belongs to class 'Eq' if there is a function named -- '(==)', of the appropriate types, defined on it class Eq a where (==) :: a -> a -> Bool instance Eq Integer where x == y = x `integerEq` y instance Eq Float where x == y = x `floatEq` y memberOf :: (Eq a) => a -> [a] -> Bool
the equality operator,
==is a function. So are
/and pretty much all operators. If a function is comprised only of special characters, it's considered an infix function by default. If we want to examine its type, pass it to another function or call it as a prefix function, we have to surround it in parentheses.
memberhas the type
a -> [a] -> Boolwith the context
(Eq a), which constrains the types which
acan range over to those
awhich belong to the
Eqclass. (Note: Haskell
=>can be called a 'class constraint'.)
- Write a polymorphic list
- Write a
list_lenfunction for it
- Write a
list_getfunction for it
- Write a identity function for it
data List a = Nil | Cons a (List a) list_len :: (List a) -> Int list_len (Nil) = 0 list_len (Cons _ xs) = 1 + list_len (xs) list_eq :: (Eq a) => List a -> List a -> Bool list_eq Nil Nil = True list_eq Nil _ = False list_eq _ Nil = False list_eq (Cons x xs) (Cons y ys) = (x == y) && (list_eq xs ys) instance (Eq a) => Eq (List a) where x == y = x `list_eq` y list_get :: List a -> Int -> a list_get (Cons x _) 0 = x list_get (Cons _ xs) index = list_get xs (index - 1)