2016-02-10 65 views
3

創建狀態的情況下在y-taka-23 adaptation of LYAH我發現,大部分片斷的第13章必須處理缺乏State構造,例如原來的Haskell代碼:弗雷格

randomSt = State random 

被改寫爲:

randomSt = do 
    gen <- State.get 
    let (x, newGen) = random gen 
    State.put newGen 
    return x 

這當然有它自己的說教優點!但是我想知道是否有另一種方法來創建State的實例。我知道Frege和Haskell之間的這種差異來自於Frege的Control.monad.State模塊中的State s a是一種抽象數據類型。是否可以定義從它派生的新的具體數據類型,並使用它的構造函數?

回答

3

難道你不能只寫一個聰明的構造函數嗎?

state :: (s -> (a, s)) -> State s a 
state f = do 
    s <- State.get 
    let (x, s') = f s 
    State.put s' 
    return x 

寫一次(可能在一個庫中,您可以下載?),然後在需要的地方使用它。

+0

是的,這個解決方案似乎像Haskell Control.Monad.Trans.State一樣模仿'state'函數,如Wikibook [here。](https:/ /en.wikibooks.org/wiki/Haskell/Understanding_monads/State) –

1

事實上,一些特定的狀態實例與

State random 

建設也相當考究,而且它在弗雷格是不可能的,因爲State數據構建器不能訪問。這是不幸的,但它也保護你不要編寫依賴於某些實現細節的代碼。

例如,我正在爲Frege開發一個新的後端,它利用Java lambda並嘗試發出類型安全的通用Java代碼,並且在做這件事的過程中,結果證明我需要另一個State的表示。因此,在下一個Frege版本中,不再需要一個函數作爲參數的構造函數State

儘管發生了這種變化,並且編譯器的大部分組件都由狀態操作組成,但我並沒有因爲這個原因而在編譯器代碼中更改任何單一行。我可以確定我不會傷害別人的代碼。大贏!

無論如何,我覺得我們可以在標準庫中包含@ jcast的智能狀態構造函數。 (我只是重寫了一個案例。)

+0

聽起來很合理,但我仍然不明白構造函數會如何破壞任何東西。 –

+0

@ libnull-dev由於構造函數揭示了這個狀態的實現細節,它與s - >(a,s)是同構的,但正如我試圖解釋的那樣,這不一定是最好的實現。當您 - stdlib使用者 - 知道構造函數時,實現無法以向後兼容的方式更改。 – Ingo

+0

好的,那麼這是否意味着'國家'可以有別於'國家'的表示? –