Экземпляр монады для простого языка 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)’

Есть идеи как это побороть?

0 ответов

Другие вопросы по тегам