微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如果定义了Option,则用于在链中应用函数的惯用Scala

是否有预先存在的/ Scala-idiomatic /更好的方法来实现这一目标?

def sum(x: Int,y: Int) = x + y

var x = 10
x = applyOrBypass(target=x,optValuetoApply=Some(22),sum)
x = applyOrBypass(target=x,optValuetoApply=None,sum)
println(x) // will be 32

我的applyOrBypass可以像这样定义:

def applyOrBypass[A,B](target: A,optValuetoApply: Option[B],func: (A,B) => A) = {
  optValuetoApply map { valuetoApply =>
    func(target,valuetoApply)
  } getorElse {
    target
  }
}

基本上我想要应用操作,具体取决于是否定义了某些Option值.如果不是,我应该得到预先存在的价值.理想情况下,我想链接这些操作,而不必使用var.

我的直觉告诉我,折叠或减少会涉及到,但我不确定它是如何工作的.或者也许还有另一种与monadic-fors有关的方法……

任何建议/提示赞赏!

解决方法

Scala有一种方法可以用于理解(如果你熟悉它,语法类似于haskell的表示法):

(for( v <- optValuetoApply ) 
  yield func(target,v)).getorElse(target)

当然,如果您要检查是否存在以下几个变量,这会更有用:

(for( v1 <- optV1
    ; v2 <- optV2
    ; v3 <- optV3
    ) yield func(target,v1,v2,v3)).getorElse(target)

如果您尝试在选项列表上累积值,那么我建议您使用折叠,因此您的可选总和将如下所示:

val vs = List(Some(1),None,Some(2),Some(3))

(target /: vs) ( (x,v) => x + v.getorElse(0) )
  // => 6 + target

在操作函数具有一些标识值的情况下,您可以概括这一点,标识:

(target /: vs) ( (x,v) => func(x,v.getorElse(identity)) )

从数学上讲,这个条件是(func,identity)形成一个Monoid.但那就是旁边的.实际效果是,无论何时达到None,对它应用func并且x将始终产生x,(忽略None,并且一些值被打开并正常应用),这就是你想要的.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐