State
モナドを と組み合わせる方法を理解しようとして、脳をねじって結び目を作っていMaybe
ます。
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
リストに number が含まれている場合に を返すように変更しましょう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
andをいじってみましたがMaybeT
、それらを機能させることができません。Monad トランスフォーマーの紹介をいくつか見てきましたが、この特定の組み合わせ (State + Maybe) に触れていなかったか、例が複雑すぎて理解できませんでした。
TL;DR:StateT
and MaybeT
(2 つの例)を使用して、この (確かに些細な) コードを記述する方法を誰かが示すことができれば幸いです。(トランスフォーマーを使わずにこのコードを書くことは不可能だと思います - それは間違っていますか?)
PS私の理解では、StateT
おそらくこの例により適していますが、それほど面倒ではないにしても、両方の例を見ることは概念的に役立ちます。
更新: @Brenton Alker が指摘したように、上記のコードの最初のバージョンは単純なタイプミス (アポストロフィがありませんでした) のために機能しません。StateT
/の使用に関する質問に焦点を当てるために、MaybeT
上記の投稿を修正しています。彼の投稿にコンテキストを与えるために、このメモを含めたかっただけです.