Bob*_*Bob 6 monads haskell state-monad deriving newtype
Haskell可以MonadState s在T1下面派生实例,但不是在T2其中是非常相似的类型.我应该以哪种方式修改代码,T2以便MonadState s可以自动派生实例?
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
import Control.Monad.Reader
import Control.Monad.State
newtype T1 r s a =
T1 { runT1 :: ReaderT r (State s) a }
deriving (Monad, MonadReader r, MonadState s)
newtype T2 r s a =
T2 { runT2 :: StateT r (State s) a }
deriving (Monad, MonadState r, MonadState s)
Run Code Online (Sandbox Code Playgroud)
你不能让一个类型有两个实例MonadState.这是因为MonadState定义为
class Monad m => MonadState s m | m -> s where
get :: m s
set :: s -> m ()
state :: (s -> (a, s)) -> m a
Run Code Online (Sandbox Code Playgroud)
关键部分是| m -> s.这需要扩展FunctionalDependencies,并声明对于任何m,我们自动知道相关联s.这意味着对于任何给定的m,只有一个选择s是有效的.所以你不能让它同时工作MonadState r m,MonadState s m除非r ~ s.如果r ~ s,那么编译器将如何知道它应用于哪个底层monad?在这种情况下,我想你也会发现,它会更容易理解和使用的代码工作,如果你创建get并put具有后缀的功能来指示,如getInner,setInner和getOuter,setOuter.
| 归档时间: |
|
| 查看次数: |
2413 次 |
| 最近记录: |