有人能带我看完这个Haskell函数(与状态monad相关)吗?
我不知道有人能带我看完这个Haskell函数(与状态monad相关)吗?,haskell,state,monads,Haskell,State,Monads,我不知道put(n+1)如何影响这个函数的最终结果。看起来这个函数应该返回初始状态不变。我试图在脑海中反复思考这个问题,但我一直没有足够的空间把东西放在合适的位置\ 如果有人能带我完成这个函数的评估,那将非常有帮助。你完全正确。勾选“功能”的“结果”是状态的初始值 当然,tick不是真正的“函数”,而是一种可以在产生结果之前读取和写入状态的计算。 在本例中,状态已更新,但仍返回状态的原始值: tick :: State Int Int tick = get >>= \n ->
put(n+1)
如何影响这个函数的最终结果。看起来这个函数应该返回初始状态不变。我试图在脑海中反复思考这个问题,但我一直没有足够的空间把东西放在合适的位置\
如果有人能带我完成这个函数的评估,那将非常有帮助。你完全正确。勾选“功能”的“结果”是状态的初始值 当然,
tick
不是真正的“函数”,而是一种可以在产生结果之前读取和写入状态的计算。在本例中,状态已更新,但仍返回状态的原始值:
tick :: State Int Int
tick = get >>= \n ->
put (n+1) >>= \y ->
return n
在这种情况下,由于您不再在勾选
中检查状态,因此您看不到已更改的状态。但是,如果在勾选之后发生其他计算,则可以看到更新的状态
例如,勾选两次(第二次将读取更新状态):
使用
do
符号编写它可能会有所帮助
-- 4 is the inital state
ghci> runState (tick >> tick) 4
(5, 6)
-- 5 is the result of the tick computation executed twice,
-- 6 is the updated state
tick::State Int
滴答
N
…如何将更新状态放在首位?它似乎只是坐在那里无所事事
啊,现在我明白你的问题了。你想知道put
(和get
)是如何工作的,对吗
也许JavaScript中的一个示例会有所帮助(一种具有实际可变状态的语言):
我希望这说明,虽然n
没有改变,但内部状态仍然会得到更新。如果执行两次tick()
,状态将增加两次
回到Haskell,这里是状态
单子的完整定义(相关部分):
var s; // mutable state
function get() { return s; }
function put(x) { s = x; }
function tick() {
var n = get();
put(n + 1);
return n;
}
现在,通过手动内联>=
,返回
,获取
和放置
,尝试进一步扩展您的示例。希望它能更清楚地了解国家是如何运作的。我不明白的是这是如何发生的。如何更新状态,但返回值保持不变?如何将状态更新放在首位?它似乎只是坐在那里无所事事。事实上,状态正在更新,但返回值,n
保持不变。看看我的另一个答案,它并没有真正的帮助。我删去了我的例子,以便我能试着理解它。我正试图弄清楚到底是什么让这种状态发生了变化。公平地说,我本来会发布get和put的定义,但我想这已经完成了。那也不会有什么帮助p我已经尽可能深入地研究了这些定义,正是这一关键细节逃过了我的眼睛。这不是你的错,这是我的错,因为我不能正确回答一个问题。我整整赢了你5秒钟!奇怪的是,我总是自己/在/我问了这个问题之后/去想事情。我很感激你的回答!:)
tick :: State Int Int
tick = do
n <- get -- get the state
put (n+1) -- save an incremented state
return n -- return the original state
var s; // mutable state
function get() { return s; }
function put(x) { s = x; }
function tick() {
var n = get();
put(n + 1);
return n;
}
newtype State s a = State { runState :: s -> (a, s) }
instance Monad (State s) where
return a = State $ \s -> (a, s)
m >>= k = State $ \s -> let
(a, r) = runState m s
in runState (k a) r
get = State $ \s -> (s, s)
put s = State $ \_ -> ((), s)