是否有可能在Scala中“嘲笑”更高级的类型?

时间:2011-06-06 04:38:45

标签: scala types currying higher-kinded-types kind-projector

假设我有一个具有两个类型参数的特征,例如

trait Qux[A, B]

和另一个具有较高类型参数的特征,例如

trait Turkle[C[_]]

我希望能够为Qux的其中一个类型参数替换固定值,以便它可以用于参数化Turkle

这是一个示例(代码在Scala中没有意义!):

trait Baz[A] extends Turkle[Qux[A, _]]

任何人都有任何想法如何实现这种效果?

5 个答案:

答案 0 :(得分:23)

Jason Zaugg想出了最简洁的方法:

trait Baz[A] extends Turkle[({type x[a]=Qux[A, a]})#x]

IntelliJ的Scala插件可选择将其折叠为:

trait Baz[A] extends Turkle[x[a]=Qux[A, a]]

答案 1 :(得分:3)

你的意思是这样的吗?

trait QuxWithString[A] extends Qux[A, String]
new Turkle[QuxWithString]{}

这是类型的部分应用模拟。

答案 2 :(得分:2)

trait Turkle[C[_]]
trait Qux[A,B]
trait Wraps[A] {
  type Jkz[X] = Qux[A,X]
  trait Baz extends Turkle[Jkz]
}

答案 3 :(得分:1)

Scala 3提议SIP: Underscore Syntax for Type Lambdas #5379,以便可能进行以下操作

trait Baz[A] extends Turkle[Qux[A, _]]

当前Dotty 0.23.0-RC1使用[X] =>> F[X]语法提供type lambdas,因此请尝试

trait Baz[A] extends Turkle[[B] =>> Qux[A, B]]

答案 4 :(得分:0)

编译器插件kind projector也允许这样做:

// Explicit lambda, greek letters
trait Baz[A] extends Turkle[λ[α=>Qux[A,α]]]

// Explicit lambda, normal letters
trait Baz[A] extends Turkle[Lambda[a=>Qux[A,a]]]

// No explicit lambda, ? placeholder    
trait Baz[A] extends Turkle[Qux[A,?]]