Suppose I have a stupid little case class like so:

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

How can I define a and b immutably such that a.other is b, and b.other is a? Does scala provide some way to "tie the knot"? I'd like to do something like this:

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

Possibilities

In Haskell I would do this:

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

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

Where the bindings to a and b are contained in the same let expression, or at the top level.

Or, without abusing Haskell's automagical letrec capabilities:

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

Note the lazy pattern, ~(a', b'), that's important.

Edit
Report