我正在将我的大脑扭成节,试图了解如何将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