在MonadState中获得并处于状态

Saw*_*yer 5 haskell

我查看了MonadState的源代码,我不明白为什么这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
Run Code Online (Sandbox Code Playgroud)

chi*_*chi 6

的定义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
Run Code Online (Sandbox Code Playgroud)

除非在实例中重新定义某些内容,否则默认的自引用实现确实很常见.