【发布时间】:2017-10-17 12:30:29
【问题描述】:
我有一个案例,我希望根据(例如,5 到 10 个)可选选项的存在对对象应用修改。所以基本上,如果我要强制执行,我的目标是:
var myObject = ...
if (option.isDefined) {
myObject = myObject.modify(option.get)
}
if (option2.isDefined) {
myObject = myObject.someOtherModification(option2.get)
}
(请注意:也许我的对象是可变的,也许不是,这不是重点。)
我认为如果我尝试实现一种流畅的编写方式会更好看,例如(伪代码...):
myObject.optionally(option, _.modify(_))
.optionally(option2, _.someOtherModification(_))
所以我从一个示例代码开始,intelliJ 没有将其突出显示为错误,但实际上并没有构建。
class MyObject(content: String) {
/** Apply a transformation if the optional is present */
def optionally[A](optional: Option[A], operation: (A, MyObject) => MyObject): MyObject =
optional.map(operation(_, this)).getOrElse(this)
/** Some possible transformation */
def resized(length : Int): MyObject = new MyObject(content.substring(0, length))
}
object Test {
val my = new MyObject("test")
val option = Option(2)
my.optionally(option, (size, value) => value.resized(size))
}
现在,就我而言,MyObject 类型属于一些外部 API,因此我创建了一个隐式转换来提供帮助,所以它的实际情况如下:
// Out of my control
class MyObject(content: String) {
def resized(length : Int): MyObject = new MyObject(content.substring(0, length))
}
// What I did : create a rich type over MyObject
class MyRichObject(myObject: MyObject) {
def optionally[A](optional: Option[A], operation: (A, MyObject) => MyObject): MyObject = optional.map(operation(_, myObject)).getOrElse(myObject)
}
// And an implicit conversion
object MyRichObject {
implicit def apply(myObject: MyObject): MyRichObject = new MyRichObject(myObject)
}
然后,我这样使用它:
object Test {
val my = new MyObject("test")
val option = Option(2)
import MyRichObject._
my.optionally(option, (size, value) => value.resized(size))
}
这一次,它在 IntelliJ 和编译时失败,因为 Option 的类型未知:
Error:(8, 26) missing parameter type
my.optionally(option, (size, value) => value.resized(size))
为了让它发挥作用,我可以:
- 主动指定
size参数的类型:my.optionally(option, (size: Int, value) => value.resized(size)) - 将
optionally重写为咖喱版本
它们都不是很糟糕,但如果我可以问:
- 是否有原因使 curried 版本有效,但多参数版本似乎无法推断参数化类型,
- 是否可以在不指定实际类型的情况下以有效的方式编写
- 作为奖励(尽管这可能是基于意见的),您将如何编写它(我想到了关于一系列选项的某种
foldLeft...)?
【问题讨论】:
标签: scala implicit-conversion type-inference