Haskell State Monad - lamba \ s的输入是什么 - > ......是吗?

时间:2016-04-15 16:28:15

标签: haskell functional-programming monads

在教程Learn You a Haskell - chapter 'for-a-few-monads-more', section 'The State monad'中,它列出了以下内容来定义State Monad:

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

instance Monad (State s) where  
    return x = State $ \s -> (x,s)  
    (State h) >>= f = State $ \s -> let (a, newState) = h s  
                                        (State g) = f a  
                                    in  g newState

只需回答一个简单的问题:\ s的输入是什么(因为状态h =一个接受状态并输出元组的函数(result,newState);暗示输入到\ s只会是那个功能)?欢迎举例

2 个答案:

答案 0 :(得分:2)

您可以将State s a的值视为一个计算,它取决于运行计算时提供的某些状态参数。你可以通过简单地展开包含的函数并调用它来实现这一点。例如

runState (return 1) "state"
=> (1, "state")

答案 1 :(得分:1)

你可以将return x描述为“给我一个州,我会把你的状态和x给你”。然后,您可以将x >>= f1视为“给我一个州,我会将其提交给x;一旦它返回状态和值,我会将这些给予f并传递f给我的东西。“

这是与功能组成的类比:

f, g, h :: a -> a
j = f . g . h :: a -> a

j是一个接受a并返回a的函数。在此过程中,该值首先被赋予h,其输出转到g,其输出转到f,其输出将被返回。

查看返回State值的函数的“组合”。

f', g', h' :: a -> State s a
j' a = return a >>= h' >>= g' >>= f'

State视为“隐藏”函数参数的一种方式。您可以像这样手动编写它们:

f'', g'', h'' :: a -> s -> (a, s)
-- We could make this point-free by leaving h curried, but this
-- is nicely consistent.
j'' a s = (uncurry f'') . (uncurry g'') . (uncurry h'') $ (a, s)

但是State monad通过>>=的实现有效地为您做到了这一点。

请注意,j'仅采用初始值,而j''采用初始值作为初始状态。那是因为j'采用该状态的函数仍然包含在State值中;我们使用runState来检索该函数,以便可以将初始状态提供给堆栈中的第一个函数。

(runState j') s0  -- parentheses optional, shown for emphasis