2016-04-15 86 views
0

是否可以在Haskell中打印state monad的結果?如何在Haskell中打印State Monad的結果?

我試圖瞭解狀態monads,並在一本書中我一直在提供下面的代碼來創建一個狀態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 
+1

「如何打印狀態單子」與「如何打印狀態單子的結果」是完全不同的問題,至少如果我將前者理解爲打印_a「狀態」action_,後者將其打印爲_打印一次執行「狀態」動作的結果。你的意思是? – leftaroundabout

+0

@leftaroundabout結果抱歉。 –

回答

2

您提供的代碼定義種事情State s a是。它也表示State s是一個單子 - 也就是說,State s符合Monad類型類別/接口。這意味着您可以將一個State s計算綁定到另一個(只要類型s在每個中相同)。

因此,您的情況類似於定義Map所屬類型的人的情況,並且還編寫了代碼,說明Map符合此類接口,但沒有任何地圖,並且還沒有對它們進行任何計算。那麼沒有什麼可以打印的。

我想你想看到評估或執行的國家行動的結果,但還沒有定義任何實際的政府行爲呢,也沒有你要求他們runState(或evalStateexecState)。不要忘記你還需要提供一個初始狀態來運行計算。

因此,可能首先讓sa爲某些特定類型。例如。讓sInt並讓aInt。現在你可以寫一些fns,例如f :: Int -> (Int, Int)g :: Int -> (Int, Int)。也許一個函數遞減狀態,返回新的狀態和值,另一個函數遞增狀態,返回新的狀態和值。然後,通過將它包裝在State的構造函數中,可以製作State Int Int,f。你可以使用>>=來連接許多國家的行爲,只要你喜歡。最後,您可以使用runState來獲得結果值和結果狀態,只要您還提供初始狀態(例如0)即可。

+0

@liminalishit非常感謝你的回答,這真的很有幫助!我做了一個函數f來增加狀態。我有點不確定如何做鏈部分抱歉,請你給我一個例子。謝謝 –

+0

讓'f = \ x - >(x + 1,x + 1)',讓'g = State(f)>> = State(f)'。這代表一個狀態動作,使狀態兩次增加。 'runState g 0'應該返回'(2,2)'。等價地,如果'h = \ x - >返回(x + 1,x + 1)',並且j ='StateT(h)>> = StateT(h)',那麼runStateT h 0返回' 2)'。這可能會讓你感覺到「State」monad的工作方式。但是使用'get'' put'和'modify'來構建狀態動作,通常來自'mtl'或'transformers'這樣的包,通常如何使用'State'單元,並且與您可能會遇到的命令式樣非常相似習慣於使用命令式語言。 – liminalisht

4

通常不可能以有意義的方式打印功能。如果函數的域很小,則可以從universe-reverse-instances包中導入Data.Universe.Instances.Show以獲得一個Show實例,該實例打印一個與該函數在語義上等效的查找表。通過導入該模塊,您可以簡單地將deriving Show添加到newtype聲明中,以便能夠在小型狀態空間上打印State操作。

1

如果它只是你想要的結果,如果你只是調試:

import Debug.Trace 
import Control.Monad.Trans.State 

action :: State [Int]() 
action = do 
    put [0] 
    modify (1:) 
    modify (2:) 
    get >>= traceShowM 
    modify (3:) 
    modify (4:) 
    get >>= traceShowM 
+0

謝謝,但我得到的錯誤不在範圍內放,修改,修改,獲取,修改,修改,獲取? –

+0

這是使用通過導入Control.Monad.Trans.State – Gurkenglas

+0

可訪問的庫提供的函數謝謝,我得到一個錯誤「模糊發生'狀態'它可以指'Main.State'或'Control.Monad .Trans.State.State'「?@Gurkenglas –