Haskell 好奇为什么get in StateT monad transformer返回a而不是(a,s)
我在读这本书,它是这样写的:Haskell 好奇为什么get in StateT monad transformer返回a而不是(a,s),haskell,Haskell,我在读这本书,它是这样写的: get :: (Monad m) => StateT s m s get = state $ \ s -> (s, s) 我通过关闭state扩展了上面的代码,得到了这个结果,但仍然不明白为什么它不返回元组 a <- StateT (return . (\ s -> (s, s))) 类型为StateT s ma的值,模为newtypewrappers,是类型为s->m(A,s)的函数 函数(return.(\s->(s,s))的类型为s
get :: (Monad m) => StateT s m s
get = state $ \ s -> (s, s)
我通过关闭state
扩展了上面的代码,得到了这个结果,但仍然不明白为什么它不返回元组
a <- StateT (return . (\ s -> (s, s)))
类型为
StateT s ma
的值,模为newtype
wrappers,是类型为s->m(A,s)
的函数
函数(return.(\s->(s,s))
的类型为s->m(s,s)
,因此,一旦被StateT
构造函数包装,它就变成了类型为StateT.ms
的值
请注意,类型为StateT s m(s,s)
的值将涉及类型为s->m(s,(s,s))
的函数,这不是我们在这里使用的
您的困惑似乎是由
m(s,s)
中的“other”s
引起的,当我们运行xget
返回类型为(StateT Int IO)String
的值时,它不会导致x
(为了更明确起见,我把括号放进去了,反正它们是隐含的),因此使用@DonKlein No,get
不返回任何内容。它是一个值,用于包装返回元组的函数。它的monad实例定义了>=
,一旦它通过运行状态(T)
实际被调用,它就会传递部分返回值,作为下一个函数的参数。请参见>=
实现的最后一行中的ka
?这意味着只有元组的一部分——即它的fst
字段——作为“返回值”从上一个计算步骤传递到下一个计算步骤,而(a,s')
中的s'
作为有状态计算“管道”的一部分进行标记。因此,我们“计算”了a
的“值”,而s
的“状态”为我们保留在一旁。请参阅答案中的一些有启发性的(希望)重写。(免责声明:其中一个由我提供)。它适用于简单状态(无变压器),因此应该更易于遵循。《变形金刚》只是在处理额外的单子,但状态传递的本质是一样的。不要在问题本身中给出答案。如果你需要付费,你可以发布自己问题的答案。
w :: StateT Int IO String
w = do
a <- get
liftIO $ print a -- 2, but why? shouldn't this be (2, 2) instead?
return $ show a
result = runStateT w 2 -- ("2",2)
global n: int
def foo():
if n > 5:
print ">5"
n = 8
return "hello"
else:
print "not >5"
n = 10
return "greetings"
Int -> IO (String, Int)
^-- the old n
^-- the printed stuff
^-- the returned string
^-- the new n
global n: int
def bar():
old_n = n
n = n + 5
return old_n
Int -> IO (Int, Int)
global n: int
def get():
return n
Int -> IO (Int, Int)