A generic használata a Haskellben sokkal természetesebb, mint más nyelvekben. Más nyelvek az általánosítási lehetőségek terén ide csúcsosodnak ki, ezért a generic az utolsóként megismert eszközök között van. Ezzel szemben a Haskell szinte innen indul, a felhasználói útmutatóknak és helpeknek már az első, de legkésőbb a második oldalán szerepelnek genericek.
A polimorf függvényeknek is kell prototípus, és ezt le kell írni valahogy. Erre használatosak a típusváltozók. Ezek legegyszerűbben úgy tekinthetők, mint olyan változók, amelyeknek értéke egy típus. Ezek a változók típuskifejezésekben szerepelnek, és a típuskifejezések írják le a függvények prototípusát. Például egy lista hosszát megadó length függvény prototípusa:
A típusváltozókra vannak műveletek is: az előbbi [a] például azt jelenti, hogy "lista a típusú elemekből", de a típusváltozókra lehet megszorítást is tenni. A megszorításoknak szintén valamilyen típusműveleteknek kell lenniük, mivel a típuskifejezések nem futási, hanem fordítási időben értékelődnek ki. Ez azt jelenti, hogy ha például azt szeretnénk leírni, hogy a length kimenő értéke egy nulla, vagy attól nagyobb egész szám, akkor ezt kénytelenek vagyunk egy kicsit körülírni, hogy fordítási időben kiértékelhető legyen: létre kell hozni egy új típust, amelynek megvan ez a megszorítása, és a típuskifejezésben ezt a típust kell használni.
A típusoknál már említettem, hogy a Haskell összes típusa valamilyen típusosztályhoz tartozik. A típuskifejezésekben megköthetjük, hogy egy típusváltozó milyen típusosztályhoz tartozó értékeket (típusokat) vehet fel.
A Haskellben nem kötelező kiírni a függvények prototípusát, mert a típusellenőrző rendszere általában jól eltalálja a megfelelőt - ezt úgy kell érteni, hogy meg tudja konstruálni azt a legáltalánosabb típust, amibe az adott függvény beletartozik. A típusellenőrzés is úgy zajlik, hogy a fordító megkonstruálja ezt a legáltalánosabb típust, aztán ellenőrzi, hogy a megadott prototípus ennek valamilyen megszorítottja-e. Ha nem, hibát jelez.
Ez a rendszer persze nem csak függvények esetében működik, hanem készíthetők polimorf adatszerkezetek, típusok is -ilyen például a Point típus is:
A Point tulajdonképpen típuskonstruktor, jelen esetben még paramétere is van. Tehát szinte minden ugyanúgy működik, mint a normális változók és függvények világában, csak nem értékekkel, hanem típusokkal dolgozunk.
Az ilyen értelemben vett polimorfizmus teljesen általános tehát a Haskellben, ezért mindezek az eszközök úgy működnek, ahogy azt az ember elvárja tőlük, nincsenek olyan kényelmetlenségek és mellékhatások, mint mondjuk a C++-ban.