要么内在也许错误处理

时间:2018-01-30 21:14:40

标签: haskell error-handling maybe either

是否有一个Haskell模式可以避免编写这个自定义函数?我的想法是将Maybe中的Nothing作为一个错误处理(作为包装的一部分):

eitherMaybeHandle :: String -> Either String (Maybe a) -> Either String a
eitherMaybeHandle err = \case
  Left e ->
    Left e
  Right Nothing ->
    Left err
  Right (Just a) ->
    Right a

4 个答案:

答案 0 :(得分:5)

首先,您可以使用sequenceEither a (Maybe b)转换为Maybe (Either a b)。然后,您可以将fromMaybea类型的值一起应用于结果,以获得Either a b

import Data.Maybe (fromMaybe)

eitherMaybeHandle :: a -> Either a (Maybe b) -> Either a b
eitherMaybeHandle err = fromMaybe (Left err) . sequence

答案 1 :(得分:3)

原始代码已经很好了。您可能需要考虑通过将每个分支保持在同一行来使其占用更少的行。

否则,只是为了替代方案,您可以使用:

eitherMaybeHandle :: String -> Either String (Maybe a) -> Either String a
eitherMaybeHandle _   (Left e)         = Left e
eitherMaybeHandle err (Right Nothing)  = Left err
eitherMaybeHandle _   (Right (Just a)) = Right a

甚至

eitherMaybeHandle :: String -> Either String (Maybe a) -> Either String a
eitherMaybeHandle _   (Left e)  = Left e
eitherMaybeHandle err (Right x) = maybe (Left err) Right x

我认为原始代码比后一种代码更具可读性。

答案 2 :(得分:2)

也许不是最简单的功能,但尝试使用monad和Maybe catamorphism ,如:

import Data.Maybe(maybe)

eitherMaybeHandle :: a -> Either a (Maybe b) -> Either a b
eitherMaybeHandle err = (>>= maybe (Left err) Right)

我们甚至可以删除err参数,并将其写成:

eitherMaybeHandle :: a -> Either a (Maybe b) -> Either a b
eitherMaybeHandle = (=<<) . flip maybe Right . Left

由于Either a是monad实例,因此我们可以使用>>=。在这种情况下,我们保持Left x不受影响,Right x将通过该函数。

作为功能,我们使用maybe :: a -> (b -> a) -> Maybe b -> a。因此,我们在Nothing上映射Left err,并在Right中使用Just x作为转换Right x的函数。

答案 3 :(得分:2)

我会使用提供

errors
note :: a -> Maybe b -> Either a b

可以与另一个Either实例合并Monad

eitherMaybeHandle :: e -> Either e (Maybe a) -> Either e a
eitherMaybeHandle err act = act >>= note err