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? 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!

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,

def n(a:T) = a.f

gives the wholly sensible yet frustrating "type T takes type parameters" error.

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.)

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.

Answers


Those are different 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. 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


Need Your Help

virtualenv + apt-get confusion

python virtualenv

I've started using virtualenv and I have a doubt, any hint will be welcome.

IBOutlet is nil inside custom UIView (Using STORYBOARD)

objective-c uiview storyboard iboutlet

I have custom UIView class. Inside it i have declared IBOutlet property for UIImageView.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.