[英]Stateful version of map (Haskell)
我剛剛學習了有關創建高階函數的知識,並且我想制作一個映射函數,該函數能夠更改適用於元組的函數,以將該函數應用於該類型的列表。 (就像map函數一樣。)我正在嘗試以具有以下簽名的方式創建它:
statefulMap :: ((a,state) -> (b,state)) -> (([a],state) -> ([b],state))
我希望能夠使用此功能來創建一系列完整的加法器,但是首先如何創建此功能?
這實際上已經存在:我們可以使用一個狀態單子和使用的一元版本的map
: mapM
。
例如,我們可以編寫一個用於完整加法器的函數。 在這里,我認為狀態是指先前完整加法器已生成的進位。
因此,我們可以將完整的加法器設為:
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
指定狀態本身的類型(此處為布爾值,即True
或False
),第二個Bool
指定我們“返回”的內容(此處為特定完整加法器的輸出為True
或False
)。
現在我們可以使用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.