Самореферентная утка - PullRequest
       1

Самореферентная утка

4 голосов
/ 02 декабря 2010

Я хочу написать функцию, которая работает с любым значением, которое может быть добавлено к другим членам своего типа (что бы «добавлено» не значило в контексте). Очевидное (хе-хе) определение такого типа:

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

Это дает мне ошибку, которую я совсем не понимаю: рекурсивный метод + нужен тип результата

Почему это не последний : Addable тип результата? Почему он все равно считает + рекурсивным?

Но я нашел более общую проблему, пытаясь сослаться на тип внутри его собственного определения:

type T = { def f: T  }     

Но тогда у меня возникла мозговая волна: решай ее так, как я бы на Яве!

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

Это скомпилировано!

Но теперь у меня есть еще две проблемы.

Во-первых, я понятия не имею, как использовать тип T. В частности,

def n(a:T) = a.f

дает совершенно разумную, но разочаровывающую ошибку "тип T принимает параметры типа".

Во-вторых, пытаясь применить этот шаблон к исходной задаче

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

приводит к совершенно непонятному «тип параметра в структурном уточнении может не относиться к абстрактному типу, определенному вне этого уточнения». (На самом деле проблема не в том, что это "+" - слава Богу и Мартину, поскольку это полностью испортило бы мою голову - просто то, что он принимает Addable в качестве параметра.)

So

  1. Как определить значение типа «утка», означающее «имеет определенную функцию, возвращающую значение того же типа»?
  2. Как определить значение типа «утка»: «имеет определенную функцию, принимающую выражение того же типа, что и параметр»?

У меня есть религиозное убеждение, что эта проблема разрешима.

1 Ответ

13 голосов
/ 02 декабря 2010

Это разные Ц.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...