2010-12-02 15 views
4

我希望编写一个函数,该函数对任何可以添加到其自己类型的成员(无论“添加”意味着上下文)中的任何值进行操作。这种类型的明显(嘿,嘿)定义:自引用鸭打字

type Addable = { def +(a : Addable) : Addable } 

这给了我一个错误,我不明白,在所有:递归方法+需要结果类型

为什么不是最后: Addable结果类型?为什么它认为+无论如何都是递归的?

但是我发现一个更一般的问题,试图引用一个类型自己的定义中:

type T = { def f: T }  

但后来我有一个脑电波:解决问题的方法我在Java中会!

type T[T] = { def f: T } 

编译!

但是现在我还有两个问题。

首先,我不知道如何使用类型T尤其

def n(a:T) = a.f 

给出了完全合理的但令人沮丧的“T型需要输入参数”的错误。

其次,试图在此模式适用于原问题

type Addable[Addable] = { def +(a : Addable) : Addable } 

导致完全不可“在结构细化参数类型可以不指代细化之外定义抽象类型”。 (实际的问题不在于它的“+” - 感谢上帝和马丁,因为这完全搞砸了我的头 - 只是,它需要可加成作为参数)

所以

  1. 我如何定义一个鸭式意义“有一个特定的函数返回相同类型的值”?
  2. 我该如何定义一个鸭式意义“有一个特定的函数采用与参数相同类型的表达式”?

我有一个宗教信仰,认为这个问题是可以解决的。

+2

见http://stackoverflow.com/questions/3466100/are-recursive-structural-types-not-supported-in-scala-anymore和http://stackoverflow.com/questions/3201577/scala-how-to-define-a--type-that-itself-to-itself – 2010-12-02 06:36:11

回答

13

这些是不同的Ts。

scala> type T[T] = { def f: T } 
defined type alias T 

scala> var x: T[Int] = null 
x: T[Int] = null 

scala> x = new AnyRef { def f = 5 } 
x: T[Int] = [email protected] 

当你写:

type Addable[Addable] = { def +(a : Addable) : Addable } 

你有一个类型可添加这需要一个单一类型的参数,也可添加叫。这是人们经常混淆的类似变化。

scala> def f[Int](x: Int) = x * x 
<console>:7: error: value * is not a member of type parameter Int 
     def f[Int](x: Int) = x * x 
          ^

实际的回答你的问题是“你不能”,但我不想打破你的宗教般的信仰所以不是我会说“结构类型以神秘的方式工作。”如果你想参加一个宗教使命,你可能会在这里访问,这就解释了为什么你不能。

http://article.gmane.org/gmane.comp.lang.scala/7013

+0

死,异端!实际上,这篇文章明确了为什么你不能在JVM中这样做。我希望Scala能够最终解决我所有的问题。呃,好吧。任务继续。 – Malvolio 2010-12-02 23:13:54