1

我正在尝试创建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 ()

类型有什么问题?

4

1 回答 1

3

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

但是,这并不是说如果您取消注释签名就是正确的。get和的类型签名put

get :: MonadState s m => m s

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

所以“正确”的类型签名是

get :: StateMonadPlus s s

put :: s -> StateMonadPlus s ()

在编写类实例时,我倾向于做与您在问题中所做的相同的事情 - 我编写类型签名但将其注释掉,以便稍后需要返回时更容易理解实例。

于 2013-10-03T12:10:04.357 回答