Вопрос по – Летрек в Скала? (Неизменный способ «завязать узел?»)

10

Предположим, у меня есть глупый маленький класс case, например:

case class Foo(name: String, other: Foo)

Как я могу определитьa а такжеb неизменно так, чтоa.other являетсяb, а такжеb.other являетсяa? Скала предоставляет какой-то способ«завяжи узел»? Я хотел бы сделать что-то вроде этого:

val (a, b): (Foo, Foo) = (Foo("a", b), Foo("b", a)) // Doesn't work.

Возможности

В Haskell я бы сделал это:

data Foo = Foo { name :: String, other :: Foo }

a = Foo "a" b
b = Foo "b" a

Где привязки кa а такжеb содержатся в том жеlet выражение или на верхнем уровне.

Или, не злоупотребляя автоматически используемыми в Haskell возможностями letrec:

(a, b) = fix (\ ~(a', b') -> Foo "a" b', Foo "b" a')

Обратите внимание на ленивый узор,~(a', b')это важно.

Интересно, сколько поисковых систем начнут находить эти вопросы для & quot; свадьбы? ... user166390
@LuigiPlinge это решение заражает определение самого класса. Я хотел бы увидеть решение, в которомFoo не измененоtoString будет действительно возвращаться навсегда. Dan Burton
Этот вопрос является более или менее дубликатомstackoverflow.com/questions/7507965/…, Кроме того, если бы это было возможно с классами случаевtoString вернется навсегда Luigi Plinge

Ваш Ответ

1   ответ
13

Foo быть неизменным, но лень в Scala есть на сайте декларации. Это невозможно дляFoo быть нестрогим, не меняя его, и шаблон, указанный в Haskell, работает только потому, чтоFooтам не является строгим (то естьFoo "a" b не оцениваетb немедленно).

В остальном решение почти такое же, учитывая обручи, необходимые для получения всего нестрогого:

class Foo(name: String, other0: => Foo) { // Cannot be case class, because that mandates strictness
  lazy val other = other0 // otherwise Scala will always reevaluate
}
object Foo {
  def apply(name: String, other: => Foo) = new Foo(name, other)
}

val (a: Foo, b: Foo) = (Foo("a", b), Foo("b", a))
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceededdata Foo = Foo { name :: !String, other :: !Foo }Error: User Rate Limit Exceeded Dan Burton

Похожие вопросы