В Haskell’е модуль является единственным способом создать так называемые абстрактные типы данных, т.е. такие, в которых скрыто представление типа, но открыты только специфические операции над созданным типом, набор которых вполне достаточен для работы с типом. Например, хотя тип Tree является достаточно простым, его все-таки лучше сделать абстрактным типом, т.е. скрыть то, что Tree состоит из Leaf и Branch. Это делается следующим образом:
module TreeADT (Tree, leaf, branch, cell, left, right, isLeaf) where
data Tree a = Leaf a
| Branch (Tree a) (Tree a)
leaf = Leaf
branch = Branch
cell (Leaf a) = a
left (Branch l r) = l
right (Branch l r) = r
isLeaf (Leaf _) = True
isLeaf _ = False
Видно, что к внутренностям типа Tree внешний пользователь (программист) может пробраться только при помощи использования определённых функций. Впоследствии, когда создатель этого модуля захочет изменить представление типа (например, оптимизировать его), ему необходимо будет изменить и функции, которые оперируют полями типа Tree. В свою очередь программист, который использовал в своей программе тип Tree, ничего менять не будет, т.к. его программа все так же останется работоспособной.