【问题标题】:Return implicit function in Scala在 Scala 中返回隐式函数
【发布时间】:2021-04-20 13:40:05
【问题描述】:

我目前有这个设置,我有一个方法和一些隐式资源,并且该方法返回一个函数,我可以稍后在我的代码中使用。

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 以便返回函数实现隐含的方法。

这样(显然不行)

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 为玩具问题提供了一个很好的解决方案,但仅在定义期间隐式资源已在范围内时才有效。

当隐式从范围中删除时,定义失败

【问题讨论】:

  • 请注意,在 Scala 3 中,这将得到修复,您的代码将按预期工作。
  • 有趣。不过,我的代码库在 Spark 中,可能不会很快

标签: scala implicit


【解决方案1】:

你可以把它写成柯里化函数,第一次使用时使用 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 时完成的。

【讨论】:

  • 确实很聪明。我试试看
  • 它当然可以在示例中使用,但是当我尝试在定义的隐式范围之外定义函数时,它会出错。
猜你喜欢
  • 2012-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-01
  • 2017-04-27
  • 2020-01-04
  • 1970-01-01
相关资源
最近更新 更多