使用 MonadPlus 处理错误
Error handling with MonadPlus
在尝试学习一些东西时再次卡住了 Haskell。我正在尝试做的是为具有错误处理的列表实施组合 head/tail
方法。签名必须如下所示:
head' :: MonadPlus m => [a] -> m (a,[a])
但是我对 MonadPlus 的错误处理方式有点迷惑。我尝试了以下方法:
head' xs = if (length xs > 0) then Just(head xs, tail xs) else Nothing
但它抱怨:预期类型:m (a, [a]) 实际类型:可能 (a, [a])。只是为了好玩我也试过了:
head' xs = if (length xs > 0) then Just(head xs, tail xs) else Nothing `mplus` Nothing
但这不仅看起来多余,而且也不起作用。
感谢任何提示!
试试这个:
head' :: MonadPlus m => [a] -> m (a,[a])
head' xs = if null xs then mzero then return (head xs, tail xs)
mzero
是 "nothing" 或(实际上)"zero" 值,您可以在此处使用它来模拟结果缺失。它具有任何类型 x
的类型 m x
和零 m
的 monad,所以它适合这里。
相反,return
将任何值包装在任何 monad 中。特别是,您可以在 m
中插入我们的 (a,[a])
对。 (这甚至不需要 monad 是 MonadPlus
)
请注意在上面的代码中我们没有提到任何特定的 monad:该代码确实是通用的,因此它可以与任何 MonadPlus
.
一起使用
最后,我使用 null
而不是 length ... > 0
,因为 null
只检查列表中的第一个构造函数,而 length ... > 0
必须遍历所有构造函数。
您实际上可以通过切换到模式匹配来删除检查:
head' :: MonadPlus m => [a] -> m (a,[a])
head' [] = mzero
head' (x:xs) = return (x, xs)
在尝试学习一些东西时再次卡住了 Haskell。我正在尝试做的是为具有错误处理的列表实施组合 head/tail
方法。签名必须如下所示:
head' :: MonadPlus m => [a] -> m (a,[a])
但是我对 MonadPlus 的错误处理方式有点迷惑。我尝试了以下方法:
head' xs = if (length xs > 0) then Just(head xs, tail xs) else Nothing
但它抱怨:预期类型:m (a, [a]) 实际类型:可能 (a, [a])。只是为了好玩我也试过了:
head' xs = if (length xs > 0) then Just(head xs, tail xs) else Nothing `mplus` Nothing
但这不仅看起来多余,而且也不起作用。
感谢任何提示!
试试这个:
head' :: MonadPlus m => [a] -> m (a,[a])
head' xs = if null xs then mzero then return (head xs, tail xs)
mzero
是 "nothing" 或(实际上)"zero" 值,您可以在此处使用它来模拟结果缺失。它具有任何类型 x
的类型 m x
和零 m
的 monad,所以它适合这里。
相反,return
将任何值包装在任何 monad 中。特别是,您可以在 m
中插入我们的 (a,[a])
对。 (这甚至不需要 monad 是 MonadPlus
)
请注意在上面的代码中我们没有提到任何特定的 monad:该代码确实是通用的,因此它可以与任何 MonadPlus
.
最后,我使用 null
而不是 length ... > 0
,因为 null
只检查列表中的第一个构造函数,而 length ... > 0
必须遍历所有构造函数。
您实际上可以通过切换到模式匹配来删除检查:
head' :: MonadPlus m => [a] -> m (a,[a])
head' [] = mzero
head' (x:xs) = return (x, xs)