Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 在MonadState中获取put和state_Haskell - Fatal编程技术网

Haskell 在MonadState中获取put和state

Haskell 在MonadState中获取put和state,haskell,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.

我看了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
class Monad m=>MonadState s m | m->s where
--|从monad的内部返回状态。
获取::m s
get=状态(\s->(s,s))
--|替换monad中的状态。
put::s->m()
放置s=状态(\ \ \->((),s))
--|在monad中嵌入一个简单的状态操作。
州::(s->(a,s))->m a
状态f=do

类声明中的
get、put、state
的定义是默认实现,在类的实际实例中被覆盖。这样,死循环就被打破了:如果一个实例只定义了
state
,那么
get
put
将使用类中的默认实现根据它来定义。类似地,如果实例定义了
get
put
,那么
state
是默认值

例如,
Eq
type类可能定义如下:

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

除非在实例中重新定义了某些内容,否则默认的自引用实现的计算结果会一直到底是很常见的。

出于兴趣,
中的“~”让
语句做什么?@radicity它使模式“无可辩驳”。但在这种情况下,它实际上没有任何作用,因为let绑定中的模式无论如何都是无可辩驳的。一个无可辩驳的模式匹配告诉编译器您对所匹配的构造函数的看法是正确的,因此它可以延迟解构它,直到它的一个参数的值被实际强制。如果您对正在使用的构造函数的看法是错误的,那么将在那个时候引发异常,而不是更早。