Monad实例用于简单语言GADT

时间:2016-03-04 20:30:26

标签: haskell monads 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)

问题是由于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)’

任何想法如何克服这个?

0 个答案:

没有答案