Сравнение GADT и MultiParamTypeClasses

Я пытаюсь понять GADT, и я просмотрел Пример GADTв руководстве GHC. Насколько я могу судить, то же самое можно сделать с MultiParamTypeClasses:

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies,
    FlexibleInstances, UndecidableInstances #-}

class IsTerm a b | a -> b where
  eval :: a -> b

data IntTerm  = Lit Int
              | Succ IntTerm
data BoolTerm = IsZero IntTerm
data If p a   = If p a a
data Pair a b = Pair a b

instance IsTerm IntTerm Int where
  eval (Lit i)      = i
  eval (Succ t)     = 1 + eval t

instance IsTerm BoolTerm Bool where
  eval (IsZero t)   = eval t == 0

instance (IsTerm p Bool, IsTerm a r) => IsTerm (If p a) r where
  eval (If b e1 e2) = if eval b then eval e1 else eval e2

instance (IsTerm a c, IsTerm b d) => IsTerm (Pair a b) (c, d) where
  eval (Pair e1 e2) = (eval e1, eval e2)

Обратите внимание, что у нас точно такие же конструкторы и точно такой же код для eval( распространение через определения экземпляра), как в примере GHC GADTs.

Так что же такое шумиха вокруг GADT? Есть ли что-то, что я могу сделать с GADT, но не могу сделать с MultiParamTypeClasses? Или они просто предоставляют более краткий способ делать то, что я мог бы сделать с MultiParamTypeClassesвместо этого?

13
задан user1078763 12 June 2012 в 10:11
поделиться