Ana*_*Ana 3 monads haskell monad-transformers
请考虑以下代码:
run = runExcept $ do
case Just 1 of
Nothing -> throwE "escape 1"
Just x -> do
case Just 2 of
Nothing -> throwE "escape 2"
Just y -> do
case Just 3 of
Nothing -> throwE "escape 3"
Just z -> return z
Run Code Online (Sandbox Code Playgroud)
假装的Just 1,Just 2,Just 3是函数调用的返回Maybe Int.
整个函数都在一个内部,ExceptT因为我想抛出异常.但内心实际上只是Maybe被操纵的很多价值观.
那么,我是否有可能利用Maybemonad 的行为来避免阶梯套管,同时仍能抛出异常?
您似乎希望Maybe使用与哪一个失败相关的信息来丰富一系列操作(如果有的话).为什么不将丰富实现为一个简单的函数?
enrich :: MonadError e m => e -> Maybe a -> m a
enrich e Nothing = throwError e
enrich e (Just x) = return x
Run Code Online (Sandbox Code Playgroud)
我正在使用MonadError- m可以抛出类型错误的monad 类e- 来概括类型enrich.例如,我们可以使用它,如果它有型e -> Maybe a -> Except e a或者e -> Maybe a -> Either e a,因为Except和Either是的两个实例MonadError.
现在,您只需使用一次enrich将Maybe值提升到更丰富的monadic上下文中.
action = do
x <- enrich "escape 1" maybe1 -- look mum, no staircasing!
y <- enrich "escape 2" maybe2
z <- enrich "escape 3" maybe3
return [x, y, z]
Run Code Online (Sandbox Code Playgroud)
如果您使用的单子可适用地 -也就是说,你不使用先前的结果确定后计算-有概括此功能工作在任意数量的惯用方法Maybe秒.我们将把它推Maybes入一个列表,以及我们需要的额外数据来丰富它 - 在这种情况下,错误消息.然后我们可以traverse(née mapM)列表来丰富每个Maybe内部并将它们加入到更大的monadic动作中.
enrichMaybes :: (Traversable t, MonadError e m) => t (e, Maybe a) -> m (t a)
enrichMaybes = traverse (uncurry enrich)
action = enrichMaybes [("escape 1", maybe1), ("escape 2", maybe2), ("escape 3", maybe3)]
Run Code Online (Sandbox Code Playgroud)
将效果视为一流公民的能力就是为什么函数式编程是一件好事.
| 归档时间: |
|
| 查看次数: |
116 次 |
| 最近记录: |