将Eithers列表转换为带有列表的Either [英] Convert list of Eithers to an Either with a list in it

查看:77
本文介绍了将Eithers列表转换为带有列表的Either的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Haskell的初学者,我正在研究一些使用可以进行错误处理.Either的左侧元素代表错误,而右侧元素代表成功结果.该代码通常使用Either的Applicative实例,该实例似乎是为此用例设计的.

I am a beginner in Haskell and I am working on some Haskell code that uses Either for error handling. The left element of the Either represents an error, while the right element represents a successful result. The code often uses the Applicative instance of Either, which seems to be designed for this use case.

给定一个类型为 [Eerer e] 的对象,最优雅的方法是将其转变为类型为 E [r] 的对象?这样做的目的是,我们可能会从调用的某些函数中获得一个返回值数组,如果这些返回值中的任何一个是错误的,我们都希望得到该错误并丢弃其他所有内容.如果数组的多个元素有错误,我希望尽可能获得最左边的错误.

Given an object of type [Either e r], what is the most elegant way to turn it into an object of type Either e [r]? The point of this is that we might have an array of return values from some functions we called, and if any of those return values is an error, we want to get that error and throw away everything else. If multiple elements of the array have an error, I would prefer to get the left-most error if possible.

我可以通过编写以下两个函数自己解决以下问题,其中两个函数是递归的,但是有更好的方法吗?

I was able to solve this problem myself in the code below by writing two functions, one of which is recursive, but is there a better way?

type Error = [Char]

myFunc :: [Either Error a] -> Either Error [a]
myFunc = myFunc2 []

myFunc2 :: [a] -> [Either Error a] -> Either Error [a]
myFunc2 r ((Left error):rest) = Left error
myFunc2 r ((Right item):rest) = myFunc2 (r ++ [item]) rest
myFunc2 r [] = Right r

main :: IO()
main = do
  -- This prints: Right [1, 2, 3]
  putStrLn (show (myFunc [Right 1, Right 2, Right 3]))

  -- This prints: Left "division by zero"
  putStrLn (show (myFunc [Right 1, Left "division by zero", Right 3]))

推荐答案

序列 来自 Control.Monad :

sequence :: (Traversable t, Monad m) => t (m a) -> m (t a)

如:

\> import Control.Monad (sequence)

\> sequence [Right 1, Right 2, Right 3]
Right [1,2,3]

\> sequence [Right 1, Left "division by zero", Right 3]
Left "division by zero"

这篇关于将Eithers列表转换为带有列表的Either的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆