Scala 可以访问选项容器的选项运算符
我有一些函数(f2..fn),它们接受A,并返回选项[A]。这非常有效(假设f1:X=>Option[A]),例如Scala 可以访问选项容器的选项运算符,scala,Scala,我有一些函数(f2..fn),它们接受A,并返回选项[A]。这非常有效(假设f1:X=>Option[A]),例如 f1(x) flatMap f2 flatMap f3 现在我想能够记录下发生了什么,尤其是在没有人介绍的情况下。我希望能够插入一个函数,例如: log_none(m:String):Option[A] => Option[A] 如果没有遇到任何问题,则会产生日志记录的副作用 所有选项功能似乎都不适用于此(在阅读了例如tonymorris.github.io/blog/
f1(x) flatMap f2 flatMap f3
现在我想能够记录下发生了什么,尤其是在没有人介绍的情况下。我希望能够插入一个函数,例如:
log_none(m:String):Option[A] => Option[A]
如果没有遇到任何问题,则会产生日志记录的副作用
所有选项功能似乎都不适用于此(在阅读了例如tonymorris.github.io/blog/posts/scalaoption备忘单之后)
理想情况下,它会看起来像:
f1(x) <.> log_none("f1 failed") flatMap f2 <.> log_none("f2 failed") ...
f1(x)log_none(“f1失败”)平面图f2 log_none(“f2失败”)。。。
我无法立即找到一种优雅、惯用的方法来做到这一点——我看不到任何东西可以放在这个位置上。这是scalaz验证的一个很好的例子。它类似于Option,但它会给您一个错误值,而不是None 之前:
def f1(x: Int): Option[Int]
def f2(x: Int): Option[Int]
def f2(x: Int): Option[Int]
for {
x1 <- f1(x)
x2 <- f2(x1)
x3 <- f3(x2)
} yield x3
您也可以使用scala执行类似的操作,但更痛苦的是,您需要到处使用.toRightProjection
我用
Validation.FlatMap
import假装验证是一元的,尽管它不是,但是如果您的f1,2,3不需要排序,您也可以使用应用程序版本来收集多个错误 您可以使用隐式类:
scala> implicit class LogEmptyOption[A](opt: Option[A]) {
| def logNone(m: String): Option[A] = {
| if (opt.isEmpty)
| println(m)
| opt
| }
| }
defined class LogEmptyOption
scala> Option.empty[String].logNone("No Such element")
这允许您扩展(可以说)原始类,而无需实际创建新的子类 我认为,
然后,
是您在这里寻找的方法,尽管它没有那么漂亮:
(f1[A] _ andThen log_none("f1 failed"))(x) flatMap (f2[A] _ andThen log_none("f2 failed")) ...
很好的答案,我都喜欢。我认为这与我所要求的最接近,隐式类对现有代码的破坏最小,scalaz可能是最正确的方法。所以不知道该接受哪一个。我将尝试隐式类,看看结果如何。
scala> implicit class LogEmptyOption[A](opt: Option[A]) {
| def logNone(m: String): Option[A] = {
| if (opt.isEmpty)
| println(m)
| opt
| }
| }
defined class LogEmptyOption
scala> Option.empty[String].logNone("No Such element")
(f1[A] _ andThen log_none("f1 failed"))(x) flatMap (f2[A] _ andThen log_none("f2 failed")) ...