简体   繁体   English

自我指责鸭子打字

[英]Self-referential duck-typing

I wish to write a function that operates on any value that can be added to other members of its own type (whatever "added" means in context). 我希望编写一个函数,该函数可以处理任何可以添加到其自身类型的其他成员的值(无论“添加”在上下文中是什么意思)。 The obvious (heh-heh) definition of such a type: 这种类型的明显(嘿嘿)定义:

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

That gives me an error I don't understand at all: recursive method + needs result type 这给了我一个我根本不懂的错误:递归方法+需要结果类型

Why isn't that last : Addable the result type? 为什么不是最后一个: Addable结果类型? Why does it think + is recursive anyway? 为什么它认为+是递归的呢?

But I found a more general problem, trying to refer to a type inside its own definition: 但我发现了一个更普遍的问题,试图在自己的定义中引用一个类型:

type T = { def f: T  }     

But then I had a brain-wave: solve it the way I would in Java! 但后来我有了一个脑波:用Java的方式解决它!

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

This compiled! 这个汇编了!

But now I have two more problems. 但现在我还有两个问题。

First, I have no idea how to use type T. In particular, 首先,我不知道如何使用T型。特别是,

def n(a:T) = a.f

gives the wholly sensible yet frustrating "type T takes type parameters" error. 给出完全明智但令人沮丧的“类型T取类型参数”错误。

Second, attempting to apply this pattern to the original problem 其次,尝试将此模式应用于原始问题

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

leads to a completely incomprehensible "Parameter type in structural refinement may not refer to an abstract type defined outside that refinement". 导致一个完全不可理解的“结构细化中的参数类型可能不会引用在该细化之外定义的抽象类型”。 (The actual problem is not that it's "+" -- thank God and Martin, since that would complete mess up my head -- just that it takes an Addable as a parameter.) (实际的问题并不在于它是“+” - 感谢上帝和马丁,因为那会让我的脑袋变得一团糟 - 只需要一个Addable作为参数。)

So 所以

  1. How do I define a duck-type meaning "has a particular function returning a value of the same type"? 如何定义鸭子类型含义“有一个特定的函数返回相同类型的值”?
  2. How do I define a duck-type meaning "has a particular function taking a expression of the same type as a parameter"? 如何定义鸭子类型含义“有一个特定的函数采用与参数相同的表达式”?

I have a religious-like belief that this problem is solvable. 我有一种宗教般的信念,认为这个问题是可以解决的。

Those are different Ts. 那些是不同的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] = $anon$1@44daa9f1

When you write: 当你写:

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

You have a type Addable which takes a single type parameter, also called Addable. 您有一个Addable类型,它接受一个类型参数,也称为Addable。 Here's a similar variation people often confuse themselves with. 这是一个人们经常混淆的类似变化。

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
                              ^

The actual answer to your question is "you can't" but I would hate to shatter your religious-like faith so instead I'll say "structural types work in mysterious ways." 你的问题的实际答案是“你不能”,但我不想破坏你的宗教信仰,所以我会说“结构类型以神秘的方式运作”。 If you want to go on a religious mission you might visit here, which explains why you can't. 如果你想继续执行宗教任务,你可以访问这里,这就解释了为什么你不能。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM