2016-04-15 78 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