haskell - 在 MonadState 中获取 put 和状态

标签 haskell

我查看了 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,那么 getput 就使用它来定义类中的默认实现。同样,如果实例定义了 getput,则默认为 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/

相关文章:

haskell - 在 Haskell 中访问记录字段作为 'Maybe' 值

haskell - Get Monad 中的 IO

optimization - GHC 没有优化除主模块以外的模块

ubuntu - 让 Haskell 的 hsenv 在 Ubuntu 13 上运行

haskell - 为什么把sq改成point-free会改变类型

haskell - 如何编写这些函数以独立于类型 : Int vs Integer 的选择

haskell - Haskell 中的点管道 ".|"运算符是什么?

haskell - 重新排序搜索空间

performance - 如何在 Haskell 中获得 5GB 堆的控制权?

linux - 如何在Linux上的2018年安装Haskell(平台或堆栈)?