Generics let one definition work over more than one type. In Haskell, this is commonly called parametric polymorphism: a type signature contains type variables such as a or t instead of fixed types. A type variable may stand for any type, but every occurrence of that variable in one use must stand for the same type. The variable names themselves do not matter. section 2.5.2 section 3.3.2
A generic function states the relationship between its inputs and outputs without committing to particular value types. For transform :: (t -> a) -> [t] -> [a], transform accepts a function from t to a and a list of t, then produces a list of a. The input and output element types can differ, while each repeated variable remains consistent. section 2.5.2
ghci> :type transform transform :: (t -> a) -> [t] -> [a]
Inspect the generic type of transform in GHCi. The signature shows that list elements are converted by a supplied function rather than requiring a fixed element type. section 2.5.2
Specializing a generic function
If f :: Int -> String is passed to transform, t becomes Int and a becomes String. Therefore transform f accepts [Int] and returns [String]. Haskell can infer this specialization, so a definition such as g xs = transform f xs receives the type [Int] -> [String]. section 2.5.2
This flexibility makes higher-order functions useful: the same operation need not be rewritten for each element type. Mapping a function over a list is a typical case, and generic types support abstract, composable code throughout Haskell programs. section 2.5.2 section 2.6
Type parameters also appear in data types. Maybe a represents either Just a value of any chosen type or Nothing. A helper with type fromMaybe :: a -> Maybe a -> a uses one a to ensure that its default value, possible wrapped value, and result all share a type. section 3.3.2 section 3.3.2
Listing 3.6 A function to extract a value from a Maybe using a default
fromMaybe :: a -> Maybe a -> a fromMaybe _ (Just v) = v #1 fromMaybe v Nothing = v #2
See a complete generic function that extracts a Maybe value or returns a same-typed default. section 3.3.2
Keep these practical distinctions in mind:
- Parametric polymorphism uses unrestricted type variables; their repeated uses must agree on one type. section 2.5.2
- Type classes can later restrict what operations are assumed for a type variable. section 2.5.2
- Generic is also a derivable facility for generating type-class implementations from a datatype definition, including JSON and database-related classes. section 16.4
- Type-variable scope can produce confusing compiler errors when multiple helper functions are involved. section 6.0 section 6.2
Use a generic signature when an algorithm depends on the shape of data and the relationships among values, not on one concrete type. Let the compiler infer a specific use where possible, while reading each repeated type variable as a consistency requirement. section 2.5.2 section 3.3.2



















