我正在努力掌握GADTs
,并且我查看了GHC 手册中的GADT 示例。据我所知,可以用以下方法做同样的事情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)
请注意,我们有与 GHC 示例中完全相同的构造函数和完全相同的代码eval
(跨实例定义传播)GADTs
。
那么所有的绒毛是GADTs
什么?有什么我可以做而GADTs
我不能做的事情MultiParamTypeClasses
吗?还是他们只是提供了一种更简洁的方式来做我可以做的事情MultiParamTypeClasses
?