val 函数中多态性的 Scala 语法
Scala syntax for polymorphism in val functions
这可能非常简单,但我找不到关于我的问题的任何文档。
在 Scala 中有两种定义函数的方法,一种使用 def
,另一种使用 val
关键字。作为函数式编程的行家,我更喜欢后者。
现在遇到一个问题:写一个def
函数,多态类型参数没问题:
def function[T](n: T) = {print(n)} // syntactically fine
如何使用 val
关键字做同样的事情仍然让我不知所措。这种幼稚的方法在语法上是无效的:
val function[T]: (a: T) => print(a) // Doesn't compile
也就是说,我绝对有可能在这里误解了 Scala 关于多态性和泛型的方法。
这需要更高级别的类型,Scala 2 不支持它。
Scala 3 支持:
https://dotty.epfl.ch/docs/reference/new-types/polymorphic-function-types.html
在 Scala 2 中无法定义参数函数,只能定义方法。
在 Scala 3 中引入了 polymorphic function type:
val fun: [A] => A => Unit = [A] => a => println(a.toString)
Cats and friends 在 2 中使用的解决方法是具有多态性的特征 apply
trait MySpecialFunctionlikeThing {
def apply[A](a: A): Unit
}
不幸的是,单一抽象方法 (SAM) 不适用于类似的东西,因此使用了一些技巧可以轻松地将函数提升到此类方法中:
object MySpecialFunctionlikeThing {
type Arbitrary
def lift(f: Arbitrary => Unit): MySpecialFunctionlikeThing =
new MySpecialFunctionlikeThing {
def apply[A](a: A): Unit = f(a.asInstanceOf[Arbitrary])
}
}
val fun = MySpecialFunctionlikeThing.lift(a => println(a))
后者我看到了几种不同的形式:上面的一种使用存在类型,另一种使用上面的一种作为方法签名和宏来实现(参见FunctionK.lift
)。
不过,通常情况下,您可以使用返回非参数函数的参数零值方法。
def fun[A]: A => Unit = a => println(a)
这可能非常简单,但我找不到关于我的问题的任何文档。
在 Scala 中有两种定义函数的方法,一种使用 def
,另一种使用 val
关键字。作为函数式编程的行家,我更喜欢后者。
现在遇到一个问题:写一个def
函数,多态类型参数没问题:
def function[T](n: T) = {print(n)} // syntactically fine
如何使用 val
关键字做同样的事情仍然让我不知所措。这种幼稚的方法在语法上是无效的:
val function[T]: (a: T) => print(a) // Doesn't compile
也就是说,我绝对有可能在这里误解了 Scala 关于多态性和泛型的方法。
这需要更高级别的类型,Scala 2 不支持它。
Scala 3 支持: https://dotty.epfl.ch/docs/reference/new-types/polymorphic-function-types.html
在 Scala 2 中无法定义参数函数,只能定义方法。
在 Scala 3 中引入了 polymorphic function type:
val fun: [A] => A => Unit = [A] => a => println(a.toString)
Cats and friends 在 2 中使用的解决方法是具有多态性的特征 apply
trait MySpecialFunctionlikeThing {
def apply[A](a: A): Unit
}
不幸的是,单一抽象方法 (SAM) 不适用于类似的东西,因此使用了一些技巧可以轻松地将函数提升到此类方法中:
object MySpecialFunctionlikeThing {
type Arbitrary
def lift(f: Arbitrary => Unit): MySpecialFunctionlikeThing =
new MySpecialFunctionlikeThing {
def apply[A](a: A): Unit = f(a.asInstanceOf[Arbitrary])
}
}
val fun = MySpecialFunctionlikeThing.lift(a => println(a))
后者我看到了几种不同的形式:上面的一种使用存在类型,另一种使用上面的一种作为方法签名和宏来实现(参见FunctionK.lift
)。
不过,通常情况下,您可以使用返回非参数函数的参数零值方法。
def fun[A]: A => Unit = a => println(a)