我可能在文档中遗漏了一些正确的东西,但我真的无法理解它 - 我一直在通过反复试验来自学Scala.
给定一个函数f: A => C,执行以下转换的惯用方法是什么?
Either[A, B] -> Either[C, B]
Either[B, A] -> Either[B, C]
(如果我有两个这样的功能并希望转换双方,我可以一次完成所有操作还是应该按顺序应用两次成语?)
Option[A] -> Option[C]
(我觉得这应该以for (...) yield某种方式使用;我可能只是在它上面消隐,当我看到答案时会感到愚蠢)
无论如何,究竟什么是"投射" Either呢?
axe*_*l22 18
你做了一个:
either.left.map(f)
Run Code Online (Sandbox Code Playgroud)
或者:
either.right.map(f)
Run Code Online (Sandbox Code Playgroud)
你也可以使用for-understanding: for (x <- either.left) yield f(x)
这里是做的更具体的例子map上Either[Boolean, Int]:
scala> val either: Either[Boolean, Int] = Right(5)
either: Either[Boolean, Int] = Right(5)
scala> val e2 = either.right.map(_ > 0)
either: Either[Boolean, Boolean] = Right(true)
scala> e2.left.map(!_)
either: Either[Boolean, Boolean] = Right(true)
Run Code Online (Sandbox Code Playgroud)
编辑:
它是如何工作的?说你有Either[A, B].调用left或right创建一个LeftProjection或一个RightProjection对象,它是一个包含该Either[A, B]对象的包装器.
对于left包装器,后续map使用函数f: A => C来转换Either[A, B]为Either[C, B].它通过在引擎盖下使用模式匹配来检查是否Either实际上是一个Left.如果是,它会创建一个新的Left[C, B].如果没有,它只是更改创建Right[C, B]具有相同基础值的新.
对于right包装器反之亦然.实际上,这either.right.map(f)意味着 - 如果(Either[A, B])对象包含Right值,则映射它.否则,保持原样,但更改B任一对象的类型,就像您已映射它一样.
从技术上讲,这些预测仅仅是封装.在语义上,它们是一种说法,你正在做的事情,假设存储在Either对象中的值是Left或者Right.如果此假设错误,则映射不执行任何操作,但类型参数会相应更改.