我正在將我的大腦扭成節,試圖瞭解如何將State
monad與Maybe
合併。在State Monad上的錯誤處理中構建最小的Haskell示例
讓我們先從一個具體的(和故意瑣碎/不必要的)例子中,我們使用State
單子找到數字列表的總和:
import Control.Monad.State
list :: [Int]
list = [1,4,5,6,7,0,3,2,1]
adder :: Int
adder = evalState addState list
addState :: State [Int] Int
addState = do
ms <- get
case ms of
[] -> return 0
(x:xs) -> put xs >> fmap (+x) addState
酷。
現在讓我們修改它,使其返回Nothing
,如果列表包含數字0
。換句話說,evalState addState' list
應該返回Nothing
(因爲list
包含0
)。我想這可能是這個樣子......
addState' :: State [Int] (Maybe Int)
addState' = do
ms <- get
case ms of
[] -> return (Just 0)
(0:xs) -> return Nothing
(x:xs) -> put xs >> fmap (fmap (+x)) addState'
...它的工作原理,但我認爲有一個更好的方式來做到這一點...
我已經StateT
和MaybeT
和玩耍了我無法讓他們工作。我已經看了一些對Monad變形金剛的介紹,但是他們或者沒有涉及到這個特殊的組合(即State + Maybe),或者這些例子太複雜了,以至於我無法理解。
TL; DR:我會很感激,如果有人可以顯示如何使用StateT
和MaybeT
(兩個例子)來寫這個(當然微不足道)的代碼。 (我假設在不使用變壓器的情況下編寫此代碼是不可能的 - 是不正確的?)
P.S.我的理解是,StateT
可能更適合這個例子,但從概念上講,如果不是太麻煩,看兩個例子都會有所幫助。
更新:正如@Brenton Alker指出的,由於簡單的錯字(我錯過了一個撇號),我上面的第一個版本的代碼不起作用。爲了集中關注使用StateT
/MaybeT
的問題,我正在糾正上面的帖子。只是想包括這個筆記給他的職位的背景。
你我們如何運行這個'StateT'函數?你的代碼編譯(假設我在原始文章中糾正了@Brenton Alker指出的撇號),但我無法使用以下(在GHCi中)運行它:'evalState addState'list'。有什麼建議麼? – iceman 2014-11-24 02:29:23
@DipakC,'evalStateT' – luqui 2014-11-24 02:40:52