Return Scala 中的隐式函数
Return implicit function in Scala
我目前有这个设置,其中我有一个方法和一些隐式资源,方法 return 是一个我可以稍后在我的代码中使用的函数。
type AResource = Int
def testA(s: String)(implicit aResource: AResource): (Double) => (String, Int) = (d: Double) => {
(s + d, d.toInt * aResource)
}
implicit val ar:AResource = 3
val fA = testA("org: ")
fA(3.1415)
这将按预期打印 (org: 3.1415,9)
。到目前为止一切顺利
然而有时我想在一个线程中调用这个方法,这迫使我将隐式显式化。
val fA2 = testA("org2: ")(ar)(1.123)
这似乎是一个小小的不便,但问题实际上更复杂一些,因为我的方法使用了 TypeTag
并将隐式 typeTag 注入到函数中。
我正在寻找的是一种定义 testA
的方法,以便 return 函数实现隐式。
像这样(显然行不通)
def testB(s: String): (Double, AResource) => (String, Int) = (d: Double)(implicit aResource: AResource) => {
(s + d, d.toInt * aResource)
}
但是我可以 运行
testB("org2: ")(1.123)
并担心最低级别的隐式
更新:
我至少找到了这个解决方案,但还不是 100% 完美
def testC(s: String): (Double) => (AResource) => (String, Int) = (d: Double) => { implicit aResource: AResource => {
(s + d, d.toInt * aResource)
}}
val c:(String, Int) = testC("org: ")(2.4)(ar)
它确实移动了隐含的行,但我仍然必须通过硬编码传递它。
更新 2:
Tim 为玩具问题提出了一个很好的解决方案,但只因为隐式资源在定义期间已经在范围内才有效。
当从范围中删除隐式时,定义失败
你可以把它写成柯里化函数,并在第一次使用时使用 Eta 展开:
def testC(s: String)(d: Double)(implicit aResource: AResource) =
(s + d, d.toInt * aResource)
val fC = testC("org: ") _
fC(3.1415)
testC("33")(2.0)
上一个错误答案
您可以这样实施 testB
:
def testB(s: String) = {
def f(d: Double)(implicit aResource: AResource) = (s + d, d.toInt * aResource)
f _
}
两种方式都可以调用:
val fB = testB("org: ")
fB(3.1415)
testB("org2: ")(1.123)
这失败了,因为隐式解析是在 testB
内部完成的,而不是在调用 f
时完成的。
我目前有这个设置,其中我有一个方法和一些隐式资源,方法 return 是一个我可以稍后在我的代码中使用的函数。
type AResource = Int
def testA(s: String)(implicit aResource: AResource): (Double) => (String, Int) = (d: Double) => {
(s + d, d.toInt * aResource)
}
implicit val ar:AResource = 3
val fA = testA("org: ")
fA(3.1415)
这将按预期打印 (org: 3.1415,9)
。到目前为止一切顺利
然而有时我想在一个线程中调用这个方法,这迫使我将隐式显式化。
val fA2 = testA("org2: ")(ar)(1.123)
这似乎是一个小小的不便,但问题实际上更复杂一些,因为我的方法使用了 TypeTag
并将隐式 typeTag 注入到函数中。
我正在寻找的是一种定义 testA
的方法,以便 return 函数实现隐式。
像这样(显然行不通)
def testB(s: String): (Double, AResource) => (String, Int) = (d: Double)(implicit aResource: AResource) => {
(s + d, d.toInt * aResource)
}
但是我可以 运行
testB("org2: ")(1.123)
并担心最低级别的隐式
更新:
我至少找到了这个解决方案,但还不是 100% 完美
def testC(s: String): (Double) => (AResource) => (String, Int) = (d: Double) => { implicit aResource: AResource => {
(s + d, d.toInt * aResource)
}}
val c:(String, Int) = testC("org: ")(2.4)(ar)
它确实移动了隐含的行,但我仍然必须通过硬编码传递它。
更新 2:
Tim 为玩具问题提出了一个很好的解决方案,但只因为隐式资源在定义期间已经在范围内才有效。
当从范围中删除隐式时,定义失败
你可以把它写成柯里化函数,并在第一次使用时使用 Eta 展开:
def testC(s: String)(d: Double)(implicit aResource: AResource) =
(s + d, d.toInt * aResource)
val fC = testC("org: ") _
fC(3.1415)
testC("33")(2.0)
上一个错误答案
您可以这样实施 testB
:
def testB(s: String) = {
def f(d: Double)(implicit aResource: AResource) = (s + d, d.toInt * aResource)
f _
}
两种方式都可以调用:
val fB = testB("org: ")
fB(3.1415)
testB("org2: ")(1.123)
这失败了,因为隐式解析是在 testB
内部完成的,而不是在调用 f
时完成的。