Экземпляр монады для простого языка GADT
У меня есть следующий 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)
Проблема в том, что определение las не является удовлетворительным из-за типа t. На самом деле 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)’
Есть идеи как это побороть?