【发布时间】:2011-12-03 23:58:13
【问题描述】:
我正在使用 Heinrich Apfelmus 的 operational monad。 我想用结果类型的 monad 参数化解释器。 我的代码的以下版本编译:
{-# LANGUAGE GADTs #-}
import Control.Monad.Operational
data EloI a where
Display :: Int -> EloI ()
type Elo a = Program EloI a
interpret :: Monad m => (Int -> m ())
-> Elo a
-> Int
-> m a
interpret display = interp
where
interp :: Monad m => Elo a -> Int -> m a
interp = eval . view
eval :: Monad m => ProgramView EloI a -> Int -> m a
eval (Display i :>>= is) s = interp (is ()) s
现在我把最后一行改成
eval (Display i :>>= is) s = display i >> interp (is ()) s
类型推断不再成功,我得到了输出
无法从上下文 (Monad m) 中推断出 (m ~ m1)
受解释的类型签名约束 :: Monad m => (Int -> m ()) -> Elo a -> Int -> m a
(...)
当我删除 interp 的类型签名时,我得到一个额外的错误(无法推断 (a1 ~ a))。
当我将所有 m 更改为 IO 时(如操作 monad 的 tic tac toe 示例中),它会再次编译。
我是在尝试一些没有意义的事情,还是可以向 GHC 提供一些提示?我不得不承认我不确定我是否需要这种灵活性。
【问题讨论】: