简体   繁体   English

短路列表,`(a -> Either ea) -> [a] -> Either e [a]` 的类型 ... monadic 操作?

[英]Short-circuit list, type of `(a -> Either e a) -> [a] -> Either e [a]` ... monadic operation?

Consider the following function:考虑以下函数:

validateList :: (a -> Either e a) -> [a] -> Either e [a]
validateList validate []     = Right []
validateList validate (x:xs) =
    case validate x of
      Left err -> Left err
      Right y  -> case validateList validate xs of
                    Left err -> Left err
                    Right ys -> Right $ y:ys

Is there a way to write this in a more concise way?有没有办法以更简洁的方式写这个? Maybe using the >>= operator?也许使用>>=运算符?

A bit to think about because there are actually two monads here: [] and Either , although List here is not acting as a monad but just more so as a Traversable需要考虑一下,因为这里实际上有两个 monad: []Either ,虽然List这里不是作为一个 monad,而更像是一个Traversable

I believe your Traversable idea is exactly what you need.我相信您的Traversable想法正是您所需要的。

validateList :: (a -> Either e a) -> [a] -> Either e [a]
validateList = traverse

This is traverse using the Either a applicative functor and the [] traversable/foldable.这是使用Either a applicative functor 和[]traverse /可折叠的遍历。

Note that this does indeed lazy/short-circuiting: as soon as a Left is found the rest of the input list is no longer demanded.请注意,这确实会造成惰性/短路:一旦找到Left ,就不再需要输入列表的其余部分。 Here is a test using an infinite list:这是使用无限列表的测试:

> validateList (\n -> case n of 1 -> Right 56 ; 2 -> Left "fdsf") [1..]
Left "fdsf"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM