为什么 MonadReader r (StateT s m) 使用底层 monad 的实例
Why MonadReader r (StateT s m) uses an instance of the underlying monad
据我所知,我们可以实现 MonadReader s (StateT s m)
实例:
instance MonadReader s (StateT s m) where
ask = get
local f m = do
s <- get
put (f s)
m
put s
即为什么不是
class MonadReader s m => MonadState s m | s -> m where ...
同样我们可以有 Monoid s => MonadWriter s (StateT s m)
个实例。
选择之间有什么深层原因吗?
这个问题的动机是 MonadError
和 MonadWriter
是否应该
MonadChronicle
的超级 类
是的,您可以这样做,但这会违反 mtl
的精神并可能导致 API 问题。 mtl
的想法是每个标准的 monad 转换器添加一个或多个不同的效果。将 StateT
和 ReaderT
添加到转换器堆栈中可以为您提供一个状态和一个环境。如果 StateT
实现了它自己的 MonadReader
实例,那么您将只能通过两个不同的接口访问状态 blob。要将环境添加到混音中,您必须使用变形金刚 "manually"。如果您将 MonadChronicle
视为提供效果,您可能希望在编写器效果和异常效果之上分层,那么您应该将它们分开。如果您将其视为这些效果的 extension/refinement,那么超类就有意义了。
我认为,除了 StateT
的 MonadReader
实例的好的 theoretical/philosophical 原因外,我认为当前的设置也是最 实用.
有用 MonadReader
和 MonadState
提供不同的功能。然后你可以利用 ask
和 get
来做两件不同的事情。如果 ask
和 get
做同样的事情,它几乎是多余的功能。让他们分开做事情要实用得多,并且通过 MonadReader
和 MonadState
instances/interfaces.
让你更灵活地使用 StateT
这与 mappend
和 <|>
对于 Maybe
做不同事情的原因类似。这只会浪费潜在的效用:)
我想如果 StateT
对 ask
和 get
给出相同的行为,人们会抱怨 impractical/limiting 会怎样。
据我所知,我们可以实现 MonadReader s (StateT s m)
实例:
instance MonadReader s (StateT s m) where
ask = get
local f m = do
s <- get
put (f s)
m
put s
即为什么不是
class MonadReader s m => MonadState s m | s -> m where ...
同样我们可以有 Monoid s => MonadWriter s (StateT s m)
个实例。
选择之间有什么深层原因吗?
这个问题的动机是 MonadError
和 MonadWriter
是否应该
MonadChronicle
是的,您可以这样做,但这会违反 mtl
的精神并可能导致 API 问题。 mtl
的想法是每个标准的 monad 转换器添加一个或多个不同的效果。将 StateT
和 ReaderT
添加到转换器堆栈中可以为您提供一个状态和一个环境。如果 StateT
实现了它自己的 MonadReader
实例,那么您将只能通过两个不同的接口访问状态 blob。要将环境添加到混音中,您必须使用变形金刚 "manually"。如果您将 MonadChronicle
视为提供效果,您可能希望在编写器效果和异常效果之上分层,那么您应该将它们分开。如果您将其视为这些效果的 extension/refinement,那么超类就有意义了。
我认为,除了 StateT
的 MonadReader
实例的好的 theoretical/philosophical 原因外,我认为当前的设置也是最 实用.
有用 MonadReader
和 MonadState
提供不同的功能。然后你可以利用 ask
和 get
来做两件不同的事情。如果 ask
和 get
做同样的事情,它几乎是多余的功能。让他们分开做事情要实用得多,并且通过 MonadReader
和 MonadState
instances/interfaces.
StateT
这与 mappend
和 <|>
对于 Maybe
做不同事情的原因类似。这只会浪费潜在的效用:)
我想如果 StateT
对 ask
和 get
给出相同的行为,人们会抱怨 impractical/limiting 会怎样。