返回空动作时如何改变状态
How can one mutate a state when returning an empty action
学习haskell有一段时间了,刚刚读完'Learn you a Haskell for great good'。我的问题来自我目前正在尝试完成的作业。基本上,我一直在使用 Snap Framework,目前我很难理解状态(在本例中是 Request + Response 对象,即 MonadSnap)在进行如下调用时是如何发生变化的:
modifyResponse :: MonadSnap m => (Response -> Response) -> m ()
我不太明白 modifyResponse 方法如何在仅将其指定为类型约束的情况下改变底层 MonadSnap
。
我在搜索答案时遇到了这个类似的概念,我相信如果我想保持状态并使以下功能按预期工作,同样的答案也会适用,就像 [=14 中提出的 OP =]:
instance M Monad where ...
-- Modify the counter and do not produce any result:
incrementCounter :: M ()
decrementCounter :: M ()
-- Get the current value of the counter
readCounter :: M Integer
这是 modifyResponse
的 source code:
modifyResponse :: MonadSnap m => (Response -> Response) -> m ()
modifyResponse f = liftSnap $
smodify $ \ss -> ss { _snapResponse = f $ _snapResponse ss }
MonadSnap
类型类中唯一的函数是 liftSnap
, and the only pre-defined instance of the typeclass is the Snap
monad(定义为 liftSnap = id
)。
这只是一点点间接,目的是让该函数可以与其他实现了 MonadSnap
的类型一起工作。它使使用 Monad Transformer 堆栈变得更加容易。签名可能是:
modifyResponse :: (Response -> Response) -> Snap ()
现在,也许你的下一个问题是:"How does smodify
work?"
这是 source code:
smodify :: (SnapState -> SnapState) -> Snap ()
smodify f = Snap $ \sk _ st -> sk () (f st)
如您所见,这不是魔法,只是函数。内部 SnapState
对你是隐藏的,因为你不需要知道 Snap
的内部就可以使用它。就像你不需要了解 IO
monad 的内部结构就可以使用它一样。
MonadSnap
的每个实例都必须提供一个 liftSnap
方法:
-- | 'MonadSnap' is a type class, analogous to 'MonadIO' for 'IO', that makes it
-- easy to wrap 'Snap' inside monad transformers.
class (Monad m, MonadIO m, MonadBaseControl IO m, MonadPlus m, Functor m,
Applicative m, Alternative m) => MonadSnap m where
-- | Lift a computation from the 'Snap' monad.
liftSnap :: Snap a -> m a
这意味着只要有 MonadSnap m
就可以很容易地通过 liftSnap
.
将具体的 Snap a
转换为 m a
修改具体Snap
's state is done by succeeding with the new SnapState
和单位()
值。 sk
是成功后要做什么的成功延续。
-- | Local Snap monad version of 'modify'.
smodify :: (SnapState -> SnapState) -> Snap ()
smodify f = Snap $ \sk _ st -> sk () (f st)
{-# INLINE smodify #-}
modifyResponse
将 smodify
从 Snap a
提升到 MonadSnap m => m a
。传递给 smodify
的函数 f
是一个仅修改 SnapState
记录的 _snapResponse
字段的函数。
modifyResponse :: MonadSnap m => (Response -> Response) -> m ()
modifyResponse f = liftSnap $
smodify $ \ss -> ss { _snapResponse = f $ _snapResponse ss }
{-# INLINE modifyResponse #-}
学习haskell有一段时间了,刚刚读完'Learn you a Haskell for great good'。我的问题来自我目前正在尝试完成的作业。基本上,我一直在使用 Snap Framework,目前我很难理解状态(在本例中是 Request + Response 对象,即 MonadSnap)在进行如下调用时是如何发生变化的:
modifyResponse :: MonadSnap m => (Response -> Response) -> m ()
我不太明白 modifyResponse 方法如何在仅将其指定为类型约束的情况下改变底层 MonadSnap
。
我在搜索答案时遇到了这个类似的概念,我相信如果我想保持状态并使以下功能按预期工作,同样的答案也会适用,就像 [=14 中提出的 OP =]:
instance M Monad where ...
-- Modify the counter and do not produce any result:
incrementCounter :: M ()
decrementCounter :: M ()
-- Get the current value of the counter
readCounter :: M Integer
这是 modifyResponse
的 source code:
modifyResponse :: MonadSnap m => (Response -> Response) -> m ()
modifyResponse f = liftSnap $
smodify $ \ss -> ss { _snapResponse = f $ _snapResponse ss }
MonadSnap
类型类中唯一的函数是 liftSnap
, and the only pre-defined instance of the typeclass is the Snap
monad(定义为 liftSnap = id
)。
这只是一点点间接,目的是让该函数可以与其他实现了 MonadSnap
的类型一起工作。它使使用 Monad Transformer 堆栈变得更加容易。签名可能是:
modifyResponse :: (Response -> Response) -> Snap ()
现在,也许你的下一个问题是:"How does smodify
work?"
这是 source code:
smodify :: (SnapState -> SnapState) -> Snap ()
smodify f = Snap $ \sk _ st -> sk () (f st)
如您所见,这不是魔法,只是函数。内部 SnapState
对你是隐藏的,因为你不需要知道 Snap
的内部就可以使用它。就像你不需要了解 IO
monad 的内部结构就可以使用它一样。
MonadSnap
的每个实例都必须提供一个 liftSnap
方法:
-- | 'MonadSnap' is a type class, analogous to 'MonadIO' for 'IO', that makes it -- easy to wrap 'Snap' inside monad transformers. class (Monad m, MonadIO m, MonadBaseControl IO m, MonadPlus m, Functor m, Applicative m, Alternative m) => MonadSnap m where -- | Lift a computation from the 'Snap' monad. liftSnap :: Snap a -> m a
这意味着只要有 MonadSnap m
就可以很容易地通过 liftSnap
.
Snap a
转换为 m a
修改具体Snap
's state is done by succeeding with the new SnapState
和单位()
值。 sk
是成功后要做什么的成功延续。
-- | Local Snap monad version of 'modify'. smodify :: (SnapState -> SnapState) -> Snap () smodify f = Snap $ \sk _ st -> sk () (f st) {-# INLINE smodify #-}
modifyResponse
将 smodify
从 Snap a
提升到 MonadSnap m => m a
。传递给 smodify
的函数 f
是一个仅修改 SnapState
记录的 _snapResponse
字段的函数。
modifyResponse :: MonadSnap m => (Response -> Response) -> m () modifyResponse f = liftSnap $ smodify $ \ss -> ss { _snapResponse = f $ _snapResponse ss } {-# INLINE modifyResponse #-}