gpt4 book ai didi

haskell - 这段 haskell 代码正确吗?如果正确,为什么?

转载 作者:行者123 更新时间:2023-12-02 16:07:45 25 4
gpt4 key购买 nike

haskell wiki(此处:https://wiki.haskell.org/State_Monad)表示状态 monad 绑定(bind)运算符的定义如下:

(>>=) :: State s a -> (a -> State s b) -> State s b
(act1 >>= fact2) s = runState act2 is
where (iv,is) = runState act1 s
act2 = fact2 iv

但是,这对我来说似乎不正确,因为绑定(bind)运算符的结果是包装在构造函数中的函数,因此无法应用(我正在谈论这种模式:(act1 >>= fact2) s)

最佳答案

简而言之:State 对象本身封装状态,它封装了对象的更改状态。

事实上,State 类型定义为:

newtype State s a = State { runState :: s -> (a, s) }

其中 runState 因此是一个接受状态 s 的函数,并返回结果 a 和一个新状态。

绑定(bind)运算符 (>>=)::State s a -> (a -> State s b) -> State s b 基本上将状态更改“链接”在一起。因此,它需要一个状态改变函数 f1::s -> (a, s) 和一个函数 f2::a -> State s b,从而创建一个函数g::s -> (b, s) 可以说是封装在 State 构造函数中。因此,第二个函数 f2 接受一个 a 并返回这样的状态更改函数。

因此绑定(bind)运算符可以定义为:

(State f1) >>= f2 = State $ \i -> let (y, s) = f1 i in runState (f2 y) s

这里我们将 i 作为初始状态,因此我们将首先通过 f1 状态转换器“链接”i。这将返回一个 2 元组:y 是该调用的“结果”,s 是新状态,然后我们将结果和新状态传递给f2。请注意,这里我们根本不进行状态更改,我们只构造一个可以执行此操作的 State 对象。因此,我们推迟了真正的链接。

如果 State 的定义如上,那么这段代码与该定义不匹配,它定义了它,如 @HTWN says ,如:

type State s a = s -> (a, s)

在这种情况下,它是正确的,因为 runState 就是 id 函数,从那时起:

(>>=) :: State s a -> (a -> State s b) -> State s b
(>>=) act1 fact2 = f
where f s = act2 is
where (iv,is) = act1 s
act2 = fact2 iv

为了使其与我们的 State 类型兼容,我们添加了一些逻辑来将其展开并包装在 State 数据构造函数中:

(>>=) :: State s a -> (a -> State s b) -> State s b
(>>=) act1 fact2 = State f
where f s = runState act2 is
where (iv,is) = runState act1 s
act2 = fact2 iv

那么确实是正确的。主要错误是没有将其包装在 State 数据构造函数中。

关于haskell - 这段 haskell 代码正确吗?如果正确,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54732806/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com