我有以下GADT代表一种简单的布尔语和 整数。
{-# LANGUAGE GADTs #-}
module Example1 where
import Control.Monad (ap)
data Expr t a where
Lit :: t -> Expr t a
Var :: a -> Expr t a
Add :: Expr Int a -> Expr Int a -> Expr Int a
Cmp :: Expr Int a -> Expr Int a -> Expr Bool a
instance Functor (Expr t) where
fmap f (Lit t) = Lit t
fmap f (Var v) = Var $ f v
fmap f (Add e1 e2) = Add (fmap f e1) (fmap f e2)
fmap f (Cmp e1 e2) = Cmp (fmap f e1) (fmap f e2)
instance Applicative (Expr t) where
pure = Var
(<*>) = ap
instance Monad (Expr t) where
return = Var
(Lit t) >>= f = Lit t
(Var v) >>= f = f v
(Add e1 e2) >>= f = Add (e1 >>= f) (e2 >>= f)
(Cmp e1 e2) >>= f = Cmp (e1 >>= f) (e2 >>= f)
问题是由于t的类型,bind的las定义不令人满意。实际上ghc会抱怨以下错误(Cmp的每个组件都有一个错误):
example1.hs:26:46:
Couldn't match type ‘Bool’ with ‘Int’
Expected type: a -> Expr Int b
Actual type: a -> Expr t b
In the second argument of ‘(>>=)’, namely ‘f’
In the second argument of ‘Cmp’, namely ‘(e2 >>= f)’
任何想法如何克服这个?