2016-04-15 54 views
1

在教程Learn You a Haskell - chapter 'for-a-few-monads-more', section 'The State monad',它列出了以下定义国家单子:Haskell State Monad - 对lamba s - > ...的输入是什么?

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的输入只是该函数)?欢迎举例

+1

's'是当前状态,'State' newtype包装的函数返回结果和新状态。 – Lee

+0

但是'现状'来自哪里呢?它来自定义的第一行:'Monad(State s)'实例吗?暗示输入是's'?需要使用定义本身的冷酷答案。 – SoyTeins

+0

不,还有一个'runState'函数,它使初始状态和计算运行,例如'runState(return 1)“state”=>(1,“state”)' – Lee

回答

2

您可以将State s a的值看作是一种计算,它取决于计算运行时提供的某些状态参数。您可以通过简单地解开所包含的函数并将其调用

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

同意上面 – SoyTeins

+0

@SoyTeins - 什么你同意吗?我编辑了答案以回应评论,因此不再适用。 – Lee

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单子有效会替你对其实施的>>=

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

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