我只是在现实世界的Haskell中研究monad变换器 . 这本书说要制作monad变换器,你需要使它成为MonadTrans类型的一个实例 .
所以这本书定义了一个新的Transformer,即 MaybeT m a
变压器 .
他们为这个新的变换器定义了monadTrans类型:
instance MonadTrans MaybeT where
lift m = MaybeT (Just `liftM` m)
然后他们为这个变换器创建了一个MonadState实例:
instance (MonadState s m) => MonadState s (MaybeT m) where
get = lift get
put k = lift (put k)
根据我的理解,提升功能正在采用底层monad并将其包装在正确的构造函数中 . 但是,我没有得到get或put的MonadState类型的实现,我想帮助理解一下这里的电梯实际做了什么 . 我还听说在mtl包中因为类型类的定义方式,你可以使用WriterT,StateT等堆栈的monad变换器,但是你可以使用get,put,tell等函数而不需要实际提升 . 我想知道这是如何工作的,我强烈怀疑它与这些类型类有关,但我不确定?
1 回答
这是因为这些功能实际上是在例如
MonadState
类型类,而不是State
类型 .然后,
State
和StateT
都成为该类的一个实例,这使得使用那些可能的1在你的示例实例中,如果我们知道
MaybeT m
的内部monad是(履行)MonadState s
,我们可以将整个外部monad视为MonadState s
,条件是我们提升指向内部monad的操作,使它们适合外部monad,这与lift
.用简单的英语来说,这听起来像“如果MaybeT变换器转换(包装)某些monad
m
,这是类型s
的有状态(MonadState
)monad,结果类型也是该类型的有状态monad” .1这实际上只是一个实例,因为
State s a
实际上实现为StateT s Identity a
. Refer to the sources了解实施细节 .