簡體   English   中英

地圖的有狀態版本(Haskell)

[英]Stateful version of map (Haskell)

我剛剛學習了有關創建高階函數的知識,並且我想制作一個映射函數,該函數能夠更改適用於元組的函數,以將該函數應用於該類型的列表。 (就像map函數一樣。)我正在嘗試以具有以下簽名的方式創建它:

statefulMap :: ((a,state) -> (b,state)) -> (([a],state) -> ([b],state))

我希望能夠使用此功能來創建一系列完整的加法器,但是首先如何創建此功能?

這實際上已經存在:我們可以使用一個狀態單子和使用的一元版本的mapmapM

例如,我們可以編寫一個用於完整加法器的函數。 在這里,我認為狀態是指先前完整加法器已生成的進位。

因此,我們可以將完整的加法器設為:

import Control.Monad.State.Lazy

fa :: (Bool, Bool) -> State Bool Bool
fa (a, b) = do
   ci <- get
   let d = a /= b
   put ((ci && d) || (a && b))
   return (ci /= d)

類型意味着我們創建了一個改變狀態的函數。 第一個Bool指定狀態本身的類型(此處為布爾值,即TrueFalse ),第二個Bool指定我們“返回”的內容(此處為特定完整加法器的輸出為TrueFalse )。

現在我們可以使用mapM制作一個有狀態的地圖:

fullAdders :: [(Bool, Bool)] -> State Bool [Bool]
fullAdders = mapM fa

因此,這需要一個2元組的列表(每個完整加法器的輸入),並產生一個State Bool [Bool] ,因此該狀態仍然是Bool ,但是現在的結果是一個booleans [Bool]的列表:一個列表包含每個完整加法器的輸出。

我們現在可以用fullAdders [(True, True), (True, False), (False, False), (True, True)]來稱呼它,但是這不會給我們布爾值列表,而是State Bool [Bool] 我們可以通過指定初始狀態來“ 運行 ”狀態monad。 我們可以通過使用runState :: State ab -> a -> (a, b)來做到這一點,因此可以使用以下命令來調用它:

runState (fullAdders [(True, True), (True, False), (False, False), (True, True)]) False

這將產生:

Prelude Control.Monad.State.Lazy> runState (fullAdders [(True, True), (True, False), (False, False), (True, True)]) False
([False,False,True,False],True)

因此,一個2元組的結果為第一項,新狀態為第二項(這里為True ,因為最后一個完整加法器的進位輸出將為True )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM