我查看了 MonadState source code ,我不明白为什么这3个函数不会进入死循环?如何评估这一点?
class Monad m => MonadState s m | m -> s where
-- | Return the state from the internals of the monad.
get :: m s
get = state (\s -> (s, s))
-- | Replace the state inside the monad.
put :: s -> m ()
put s = state (\_ -> ((), s))
-- | Embed a simple state action into the monad.
state :: (s -> (a, s)) -> m a
state f = do
s <- get
let ~(a, s') = f s
put s'
return a
最佳答案
class 声明中的 get,put,state
定义是默认实现,它们应该在类的实际实例中被覆盖。这样,死循环就被打破了:如果一个实例只定义了 state
,那么 get
和 put
就使用它来定义类中的默认实现。同样,如果实例定义了 get
和 put
,则默认为 state
。
例如,Eq
类型类可能定义如下:
class Eq a where
(==) :: a -> a -> Bool
x == y = not (x /= y)
(/=) :: a -> a -> Bool
x /= y = not (x == y)
instance Eq Bool where
True == True = True
False == False = True
_ == _ = False
-- the (/=) operator is automatically derived
instance Eq () where
() /= () = False
-- the (==) operator is automatically derived
默认的自引用实现确实很常见,除非在实例中重新定义了某些内容,否则其计算结果为底部。
关于haskell - 在 MonadState 中获取 put 和状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23149318/