自我指责鸭子打字

时间:2010-12-02 05:45:20

标签: scala

我希望编写一个函数,对任何可以添加到其自身类型的其他成员的值进行操作(无论“添加”在上下文中是什么意思)。这种类型的明显(嘿嘿)定义:

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 }

导致完全不可理解的“结构细化中的参数类型可能不会引用在该细化之外定义的抽象类型”。 (实际问题不在于它是“+” - 感谢上帝和马丁,因为那样会让我的头脑变得一团糟 - 只需要一个Addable作为参数。)

所以

  1. 如何定义鸭子类型含义“具有返回相同类型值的特定函数”?
  2. 如何定义鸭子类型含义“有一个特定的函数采用与参数相同的表达式”?
  3. 我有一种宗教般的信念,认为这个问题是可以解决的。

1 个答案:

答案 0 :(得分:13)

那些是不同的。

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] = $anon$1@44daa9f1

当你写:

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

您有一个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