在Scala中,?=>是什么意思?

11

我看到过 ?=> 符号出现在Scala代码和一些关于Scala 3的讨论帖中,所以我认为它是Scala 3+符号。在搜索文档或Google时没有找到任何结果,但它看起来像是对Function类型的语法糖,所以也许与类型和函数有关。它是什么意思呢?


8
https://docs.scala-lang.org/scala3/reference/contextual/context-functions.html - Luis Miguel Mejía Suárez
3
我给你点赞。Scala 3 的文档还没有完全就位,并且在最初的dotty提案和实际进入语言中之间导航有些困难。这肯定是当前一个非常合理的问题。 - sinanspd
2
在某个时候,有人需要撰写一篇关于Scala 3中不同函数的良好博客文章。有普通函数类型、上下文函数类型、依赖函数类型和多态函数类型。虽然从类型理论的角度来看它们都非常酷(而且真正令人惊奇的是,一个通用的非纯学术语言成功地实现了它们),但我很想看到一篇关于每种类型实际应用的精心撰写的文章。 - Silvio Mayolo
1个回答

5

(a: A, b: B, ..., z: Z) ?=> R的类型基本上意味着(using a: A, b: B, ..., z: Z) => R(我相信后一种语法曾经是有效的,但现在不再有效)。当使用?=>时,所有这些参数都变成隐式参数。同样地,函数文本(a, b, ..., z) ?=> ...使得该函数的所有参数都变为隐式参数,并且它们可以被传递给其他方法。

以下是一个示例 (Scastie):

case class Foo(s: String)
case class Bar(i: Int)

def baz(xyzzy: (Foo, Bar) ?=> String): Unit =
  val foo = Foo("waldo")
  val bar = Bar(2)
  println(xyzzy(using foo, bar))

baz接受一个上下文函数。请注意,xyzzy的语法与正常的方法相同,它需要一个FooBar作为隐式参数(在Scala 3中,使用blah(using bleh, bluh)来显式地传递隐式参数blehbluh,而不是像在Scala 2中那样简单地使用blah(bleh, bluh))。

以下是我们调用baz的一种方法,通过定义带有隐式参数的方法:

def foobar(using Foo, Bar) =
  val foo = summon[Foo]
  val bar = summon[Bar]
  s"Method - foo: $foo, bar: $bar"

baz(foobar)

我们还可以传入一个函数字面量。它没有普通参数,所以看起来有点像按名称的参数。由于字面量的 (Foo, Bar) ?=> 类型,因此可以使用 FooBar 的隐式实例。

baz {
  val foo = summon[Foo]
  val bar = summon[Bar]
  s"Function literal - foo: $foo, bar: $bar"
}

您还可以在函数文本本身中使用?=>来命名隐式参数,而无需召唤它们并将其分配给值。由于它们是隐式的,因此您也可以从上面调用foobar,因为有一个隐式的FooBar可用(即使没有明确命名参数,您也可以在第二个示例中这样做)。

baz { (foo: Foo, bar: Bar) ?=>
  val fromMethod = foobar
  s"Explicit context function literal - foo: $foo, bar: $bar; $fromMethod"
}


这在Scala 2中会如何表示?在Scala 2类型系统中,Foo => Bar是否与Foo ?=> Bar相同? - Ian
3
我认为在Scala 2中没有简单的方法来实现它,除非创建一个带有两个隐式参数的方法的特质ContextFunction2[A, B] - user

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接