微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Scala泛型函数与泛型方法

如何解决Scala泛型函数与泛型方法

到目前为止,我的印象是,在scala中定义泛型函数的唯一方法是使用方法

def myToString[A](value: A) = {println(value)}

但是我想出了以下方法

val myToStringFun: (T forSome {type T}) => Unit = value => println(value)

是否有我看不见的东西,还是在不使用方法的情况下在Scala中编写泛型函数的模式?

我以前从未见过这种模式,只是根据我对“高级类型”和“存在性...”概念的了解而提出的。

分享您对此的想法或智慧。...

EDIT1:

如果上述正确,为什么不使用此模式而人们系统地使用通用函数方法。这只是一种简便的表达方式

EDIT2:

如果函数(T forSome {type T}) => Unit Any => Unit

但是,似乎

val mySeqToString: (Seq[T] forSome {type T}) => String = {
    case head +: tail => s"$head +: " + seqToString(tail)
    case Nil => "Nil"
}

等同于

def seqToString[T](seq: Seq[T]): String = seq match {
    case head +: tail => s"$head +: " + seqToString(tail)
    case Nil => "Nil"
}

正确吗?

解决方法

函数中的类型A是标准的泛型类型。您可以使用它做很多事情,例如要求一个typeclass实例:

import cats.implicits._
def myToString[A: cats.Show](value: A) = { println(value.show) }

另一方面,键入(T forSome {type T})existential type。您可能会以其更流行的速记符号_(例如List[_])来识别它。您不能对此做太多。如果您在{p>中检查value的类型

val myToStringFun: (T forSome { type T }) => Unit = value => println(value)

您会注意到它是Any。顺便说一句,通过forSome使用存在类型为being dropped

在Scala中,函数是单态的,与多态的方法不同。我个人认为,this文章对此主题做了很好的解释。

,

(T forSome { type T })只是Any,所以(T forSome { type T }) => UnitAny => Unit,它是任意A => Unit子类型。>

通常F[T] forSome { type T }不是F[Any](对于协变F就是F[+X]来说是如此)。 F[T] forSome {type T}亦称F[_]是所有F[A](包括F[Any])类型的超类型。实际上,它是最小的此类超类型,即所有类型F[A]的最小上限(对于固定F和任意A)。

但是,似乎

val mySeqToString: (Seq[T] forSome {type T}) => String = {
  case head +: tail => s"$head +: " + seqToString(tail)
  case Nil => "Nil" 
}

等同于

def seqToString[T](seq: Seq[T]): String = seq match {
  case head +: tail => s"$head +: " + seqToString(tail)
  case Nil => "Nil" 
}

正确吗?

否。

def seqToString[T](seq: Seq[T]): String是通用的quantification

seqToString: (∀ T) => (seq: Seq[T]) => String

val mySeqToString: (Seq[T] forSome {type T}) => String是存在性量化

seqToString: ((∃ T),(seq: Seq[T])) => String

在第一种情况下,您可以指定T,您的代码将适用于此特定的T,例如seqToString[Int]将接受Seq[Int]seqToString[String]将接受Seq[String]等。

在第二种情况下,您不控制T,该方法接受所有Seq[Int]Seq[String]等。

由于Seq是协变的,所以Seq[T] forSome { type T }只是Seq[Any]

在依赖类型语言对Sigma类型的存在量化leads中,通用量化导致Pi类型。

,

Scala 3(Dotty)应提供polymorphic function types,类似于多态方法

scala> def myToString[A](value: A) = println(value)
def myToString[A](value: A): Unit

我们可以编写多态函数

scala> val myToString: [A] => A => Unit = [A] => (value: A) => println(value)
val myToString: PolyFunction{apply: [A](x$1: A): Unit} = <function1>

等效于PolyFunction,它使用多态apply方法进行了精炼

scala> val myToString: PolyFunction {def apply[A](value: A): Unit} = new PolyFunction {
     |   def apply[A](value: A): Unit = println(value)
     | }
val myToString: PolyFunction{apply: [A](value: A): Unit} = <function1>

请不要混淆多态函数类型

[A] => B

lambda类型位于另一个“级别”上

[A] =>> B

其中箭头> lifts中第二个=>>为类型级别。

请注意,此功能仍按照documentation is missing polymorphic functions #7594进行操作

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。