我的get和put类型签名有什么问题?

时间:2013-10-03 12:05:13

标签: haskell monads type-signature

我正在尝试将StateMonadPlus作为MonadState的实例。

data StateMonadPlus s a = StateMonadPlus (s -> Either String (a, s))

instance MonadState s (StateMonadPlus s) where
    -- get :: StateMonadPlus s
    get = StateMonadPlus (\s -> Right (s, s))
    -- put :: s -> StateMonadPlus ()
    put s = StateMonadPlus (\_ -> Right ((), s))

代码编译得很好,但是当我取消注释get和put的类型时,它抱怨

A3.hs:17:5: Misplaced type signature: get :: StateMonadPlus s

A3.hs:19:5: Misplaced type signature: put :: s -> StateMonadPlus ()

这些类型有什么问题?

1 个答案:

答案 0 :(得分:3)

您收到编译器错误,因为类型签名不属于那里。您不能在实例声明中放置类型签名,因为类型已经由类声明中的签名确定。

但是,如果您取消注释,那并不是说签名是正确的。 getput的类型签名是

get :: MonadState s m => m s

put :: MonadState s m => s -> m ()

所以'正确'类型签名是

get :: StateMonadPlus s s

put :: s -> StateMonadPlus s ()

在编写类实例时,我倾向于做与你在问题中所做的相同的事情 - 我写了类型签名但是将其注释掉,这样如果我需要稍后再回来它就更容易理解实例。