Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.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 好奇为什么get in StateT monad transformer返回a而不是(a,s)_Haskell - Fatal编程技术网

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
引起的,当我们运行
x
get
返回类型为
(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)