我们可以在Scala中定义更高级的类型级别标识函数吗?

时间:2010-09-05 09:41:33

标签: scala functional-programming types higher-kinded-types

在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型。

是否有一些聪明的编码可以解决这个问题?或者现在就不可能了?

3 个答案:

答案 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。