Seb*_* N. 7 monads coding-style scala optional-parameters named-parameters
是否有预先存在/ 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
Run Code Online (Sandbox Code Playgroud)
我的applyOrBypass可以像这样定义:
def applyOrBypass[A, B](target: A, optValueToApply: Option[B], func: (A, B) => A) = {
optValueToApply map { valueToApply =>
func(target, valueToApply)
} getOrElse {
target
}
}
Run Code Online (Sandbox Code Playgroud)
基本上我想要应用操作,具体取决于是否定义了某些选项值.如果不是,我应该得到预先存在的价值.理想情况下,我想链接这些操作,而不必使用var.
我的直觉告诉我,折叠或减少会涉及到,但我不确定它是如何工作的.或者也许有另一种方法与monadic-fors ...
任何建议/提示赞赏!
Scala有一种方法可以用于理解(do如果你熟悉它,语法类似于haskell的表示法):
(for( v <- optValueToApply )
yield func(target, v)).getOrElse(target)
Run Code Online (Sandbox Code Playgroud)
当然,如果您要检查是否存在以下几个变量,这会更有用:
(for( v1 <- optV1
; v2 <- optV2
; v3 <- optV3
) yield func(target, v1, v2, v3)).getOrElse(target)
Run Code Online (Sandbox Code Playgroud)
如果你试图在一个选项列表上积累一个值,那么我会推荐一个折叠,所以你的可选总和将如下所示:
val vs = List(Some(1), None, None, Some(2), Some(3))
(target /: vs) ( (x, v) => x + v.getOrElse(0) )
// => 6 + target
Run Code Online (Sandbox Code Playgroud)
在您的操作func具有某些标识值的情况下,您可以对此进行概括identity:
(target /: vs) ( (x, v) => func(x, v.getOrElse(identity)) )
Run Code Online (Sandbox Code Playgroud)
在数学上说这个条件是(func, identity)形成一个Monoid.但那是旁边的.实际效果是,无论何时None达到,应用func它x并将始终产生x,(None's被忽略,Some值被解开并正常应用),这就是你想要的.
在这种情况下我会做的是使用部分应用的函数和identity:
def applyOrBypass[A, B](optValueToApply: Option[B], func: B => A => A): A => A =
optValueToApply.map(func).getOrElse(identity)
Run Code Online (Sandbox Code Playgroud)
你可以像这样应用它:
def sum(x: Int)(y: Int) = x + y
var x = 10
x = applyOrBypass(optValueToApply=Some(22), sum)(x)
x = applyOrBypass(optValueToApply=None, sum)(x)
println(x)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1717 次 |
| 最近记录: |