Scala: работа вокруг "нелегальной циклической ссылки" - PullRequest
6 голосов
/ 28 апреля 2010

Я пытаюсь реализовать дерево на основе HashMap, которое бы поддерживало поиск поддерева O (1) для данного корневого ключа. С этой целью я пытаюсь сделать следующее:

scala> type Q = HashMap[Char, Q]
<console>:6: error: illegal cyclic reference involving type Q
       type Q = HashMap[Char, Q]
                          ^

Итак, вопрос в том, могу ли я сделать что-то подобное, не прибегая к уродливому HashMap[Char, Any] с последующим приведением значений к HashMap[Char, Any]?

Теперь я также вижу, что могу использовать что-то вроде следующего, чтобы избежать ошибки циклической ссылки, и это может быть даже чище - но было бы неплохо узнать, как правильно сделать это первым способом, только для образовательной ценности.

import collections.mutable.HashMap

class LTree {
  val children = new HashMap[Char, LTree]
}

Спасибо большое.

Ответы [ 2 ]

16 голосов
/ 08 мая 2010

Я, вероятно, не "понимаю" вопрос, но как насчет

class L {
  type Q = java.util.HashMap[Char, this.type]
}

или

class Q extends java.util.HashMap[Char, Q]
1 голос
/ 19 марта 2014

Для типов, которые вы не можете extend, например Either, вы также можете использовать тривиальную оболочку:

class MyEither(get: Either[String, MyEither])

или рекурсивное дерево с Either (что привело меня к этой теме):

// represents (validation) errors for a tree structure of nested dictionaries
type FieldName = String
type Error = String

type Errors = List[(FieldName, FieldError)]
case class FieldError(val get: Either[Error, Errors])

, которая является типовой версией этого псевдокода:

type Error = String
type Errors = List[(FieldName, Either[Error, Errors])]

Тогда все ваши звонки Left(...) и Right(...) станут FieldError(Left(...)) и FieldError(Right(...)) соответственно, так что, например, FieldError(Right(x)).get == Right(x).

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