假设我在调用中processOne定义了一个monadic函数,如下所示:
def processOne(input: Input): Either[ErrorType, Output] = ...
给定一个" Inputs" 列表,我想返回一个相应的列表" Outputs"包裹在Either:
def processMany(inputs: Seq[Input]): Either[ErrorType, Seq[Output]] = ...
processMany将调用processOne它具有的每个输入,但是,我希望它在第一次(如果有的话)终止processOne返回a Left,并返回它Left,否则返回Right带有输出列表的a.
我的问题:实施的最佳方式是processMany什么?是否可以使用for表达式来完成此行为,或者我是否有必要以递归方式迭代列表?
使用Scalaz 7:
def processMany(inputs: Seq[Input]): Either[ErrorType, Seq[Output]] =
inputs.toStream traverseU processOne
Run Code Online (Sandbox Code Playgroud)
转换inputs为Stream[Input]利用非严格的traverse实现Stream,即为您提供所需的短路行为.
顺便说一句,你标记了这个"monads",但遍历只需要一个applicative functor(事实上,它可能是根据monad来定义的Either).有关进一步参考,请参阅论文"迭代器模式的本质",或者,对于基于Scala的解释,Eric Torreborre 关于该主题的博客文章.