我的代码适用于受限于某种状态的monad.我遇到了问题,因为状态有一个需要monad的类型变量.
看起来像:
myget :: MonadState (MyState m A) m => m A
Run Code Online (Sandbox Code Playgroud)
现在当我试图让它更具体时,就会出现问题.例如,StateT(在某些内部monad上im):
myget' :: StateT <loops here> im A
myget' :: StateT (MyState <loop> A) im A
myget' :: StateT (MyState (MyState <loop> A) A) im A
myget' :: StateT (MyState (MyState (MyState <loop> A) A) A) im A
...
myget' = myget
Run Code Online (Sandbox Code Playgroud)
显然我不能写这种类型的签名; 我甚至不能将它留给类型推断.
我怎么解决这个问题?
我通过myget在monad变换器上进行(第一个,一般定义)工作来解决它,它确实有效,但是代码与其他任何东西都不能很好地协同工作(因为通常人们使用monad变换器就像monad一样),所以这不是一个非常好的解决方案.
有任何想法吗?
newtype来救援!ornewtype声明data可以打破循环。
newtype MS s m a = MS
{getMS :: StateT (MyState (MS s m) s) m a}
deriving (Functor, Applicative, Monad)
deriving instance Monad m =>
MonadState (MyState (MS s m) s) (MS s m)
instance MonadTrans (MS s) where
lift = MS . lift
Run Code Online (Sandbox Code Playgroud)