dk1*_*k14 11 polymorphism haskell scala type-inference
更新(2018年):我的祈祷在Dotty(Type Lambdas)得到了回答,因此以下问答更加"Scalac"相关
Scala只是一个简单的例子:
scala> def f(x: Int) = x
f: (x: Int)Int
scala> (f _)(5)
res0: Int = 5
Run Code Online (Sandbox Code Playgroud)
让我们通用:
scala> def f[T](x: T) = x
f: [T](x: T)T
scala> (f _)(5)
<console>:9: error: type mismatch;
found : Int(5)
required: Nothing
(f _)(5)
^
Run Code Online (Sandbox Code Playgroud)
让我们看看Scala中的多态方法的eta扩展:
scala> f _
res2: Nothing => Nothing = <function1>
Run Code Online (Sandbox Code Playgroud)
与Haskell的比较:
Prelude> let f x = x
Prelude> f 5
5
Prelude> f "a"
"a"
Prelude> :t f
f :: t -> t
Run Code Online (Sandbox Code Playgroud)
Haskell在[T] => [T]
这里确实推断出了正确的类型.
更现实的例子?
scala> identity _
res2: Nothing => Nothing = <function1>
Run Code Online (Sandbox Code Playgroud)
更现实:
scala> def f[T](l: List[T]) = l.head
f: [T](l: List[T])T
scala> f _
res3: List[Nothing] => Nothing = <function1>
Run Code Online (Sandbox Code Playgroud)
你不能为身份制作别名 - 必须编写自己的功能.像[T,U](t: T, u: U) => t -> u
(制作元组)这样的东西不可能用作价值观.更一般 - 如果你想传递一些依赖于泛型类型的lambda(例如:使用泛型函数,例如:创建列表,元组,以某种方式修改它们) - 你不能这样做.
那么,如何解决这个问题呢?任何解决方法,解决方案或推理?
PS我使用了术语多态lambda(而不是函数),因为函数只是名为lambda
只有方法在JVM/Scala上可以是通用的,而不是值.您可以创建一个实现某个接口的匿名实例(并为您要使用的每个类型都复制它):
trait ~>[A[_], B[_]] { //exists in scalaz
def apply[T](a: A[T]): B[T]
}
val f = new (List ~> Id) {
def apply[T](a: List[T]) = a.head
}
Run Code Online (Sandbox Code Playgroud)
或者使用无形' Poly
,它支持更复杂的类型案例.但是,这是一个限制,它需要解决.
归档时间: |
|
查看次数: |
676 次 |
最近记录: |