2010-09-04 65 views
24

我需要一些使用traits和结构类型作为类型参数约束的代码片段的递归结构类型。它工作得很好,但后来我学会了Scala不支持递归结构类型。关于Scala中(递归)结构类型的有趣观察

所以有人可以解释我为什么能正常工作:

scala> trait Test[M[A] <: { def map[B](f: A => B) : M[B] } ] {} 
defined trait Test 

,这不:

scala> def test[M[A] <: { def map[B](f: A => B) : M[B] } ] = null 
<console>:5: error: illegal cyclic reference involving type M 
     def test[M[A] <: { def map[B](f: A => B) : M[B] } ] = null 

回答

6

我认为这是编译器中的一个小故障。以下代码表现出与您的初始代码相同的行为:

trait Test[M[A] <: { def map: M[A] } ] {} 
def test[M[A] <: { def map: M[A] } ] = null 

它导致编译时错误:'非法循环引用'。

而下面的代码没有(即它编译精细):

type S[M] = { def map: M } 

trait Test[M[A] <: S[M[A]] ] {} 
def test[M[A] <: S[M[A]] ] = null 

唯一的区别是,结构打字经由类型别名应用型在这里。

+0

实际上,我喜欢使用类型别名的解决方案,它甚至可以用于函数定义。但是你的第一个例子的行为与我的完全一样,说Test-trait编译得很好。但是,如果它使用类型别名,它绝对应该工作而不使用它们?!? – urso 2010-11-18 11:11:32

+0

是的,我认为这里有一些不一致:它应该使用类型别名和不使用,或者它不应该工作。这就是为什么我认为这是编译器中的一个小故障。 – michid 2010-11-18 12:53:17

+0

你有错误跟踪器号码吗? – soc 2010-11-23 13:10:22

0

第一代码片段也抛出错误斯卡拉2.7.7final:

scala> trait Test[M[A] <: { def map[B](f: A => B) : M[B] } ] {} 
<console>:4: error: illegal cyclic reference involving type M 
     trait Test[M[A] <: { def map[B](f: A => B) : M[B] } ] {} 
                ^

你使用哪个版本的Scala?

+0

Scala中的工具2.8.1 – tstenner 2010-11-16 19:29:28

+0

我正在使用scala 2.8.0 – urso 2010-11-18 11:10:24