在Scala中,我们可以为低级别类型定义类型级别标识函数,如此,
type Id[A] = A
我们还可以为更高级别的类型定义类似的东西吗? IE浏览器。我们可以填写空白吗,
type HKId[A[...]] = ...
这样类似于HKId [List]的东西让我们回到List类型构造函数?
将自由名称绑定在诸如
之类的内容中type Foo[X] = List[X]
val l : Foo[Int] = List(1, 2, 3)
可能会让我们期待更高级别的类型级别身份,
type HKId[A[X]] = A[X]
但scalac抱怨在RHS上找不到X型。
是否有一些聪明的编码可以解决这个问题?或者现在就不可能了?
答案 0 :(得分:13)
X
中的 type HKId[A[X]] = ...
是一个更高阶的类型参数。它的作用域是type参数子句,通常在类型约束中引用。见规范§4.4:
上述范围限制是 推广到嵌套类型的情况 参数子句,声明 高阶类型参数。 高阶类型参数(类型 类型参数t)的参数是 只能立即见到他们 周围参数子句(可能 包括更深层嵌套的条款 水平)和在t的范围内。 因此,他们的名字必须只是 成对不同于。的名字 其他可见参数。自从 高阶类型参数的名称 因此,它们可能是无关紧要的 用'_'表示,这是无处可去的 可见。
前段时间,我们讨论了为类型函数添加文字语法的可能性,例如: [A] Either[Int, A]
。这在Scalaz中非常有用。与此同时,我们使用了Alexey的回答中的诀窍,用PartialApplyXofY traits表达。推理会更好,但这更加棘手,尽管有innocuous entry in Trac!)
无论如何,在那个帖子中,Adriaan mentioned:
这显然不会是微不足道的 实现逻辑上的一切 从匿名类型开始 我们目前没有的功能 允许的必要基础设施 人们写出更高级的类型 别名,例如:
输入MyTypeFun = [X,Y]对[Y,X] // 可取但很难支持 目前的实施(我们看看 推断符号的类型参数 它的那种)
<强>更新强>
事实证明你已经非常接近了:
def hk[_[_]] = ();
hk[({type A[X] = X})#A]
或者获得一点创意:
def hk[_[_]] = (); hk[({type \[X] = X}) # \ ]
def hk[_[_]] = (); hk[({type λ[α]=α})#λ ]
答案 1 :(得分:5)
无法找到以type
的方式执行此操作的方法,但这样做有效:
class HKId[A[_]] {
type Value[X] = A[X]
}
编译:
scala> List(1): HKId[List]#Value[Int]
res2: List[Int] = List(1)
这不是:
scala> List(1): HKId[List]#Value[Boolean]
<console>:7: error: type mismatch;
found : Int(1)
required: Boolean
List(1): HKId[List]#Value[Boolean]
答案 2 :(得分:3)
从@retronym中取出正确答案似乎有点不公平,但看起来我们可以更接近我所追求的那种解决方案,
scala> type HKId[A[_]] = { type λ[X] = A[X] }
defined type alias HKId
scala> def foo[C[_]] : C[Int] = null.asInstanceOf
foo: [C[_]]=> C[Int]
scala> foo[List]
res0: List[Int] = null
scala> foo[HKId[List]#λ]
res1: List[Int] = null
我不确定为什么现在看起来很明显,但一年前并不明显......也许是因为从那时起我们都习惯了更多习惯看到类型的lambdas。