2012-02-04 14 views
9

Najbliższy rzecząW bieżącym Scala, istnieje przejrzysty sposób zrobić „lazy konstruktora wzorca”

case class Foo(lazy next: Foo) 

że udało mi się wymyślić jest

class Foo(_next: =>Foo) { 
    lazy val next = _next 
} 
object Foo { 
    def apply(next: =>Foo) = new Foo(next) 
    def unapply(foo: Foo) = Some(foo.next) 
} 

znalazłem wymieniony numer: add lazy parameters, więc myślę, że pewnego dnia zostanie dodany . W międzyczasie czy ktoś zna czystszą sztuczkę niż powyższe?

+0

Warto wspomnieć, że 'metoda unapply' nie jest leniwy, więc stara się dopasować wzór' Foo' do innego 'Foo' spowoduje' next' poddawanych ocenie, która może nie chcieć. –

+0

@BrianMcCutchon To dobry punkt. Przypuszczam, że jedynym sposobem na to, aby był leniwy, byłoby dodanie indirectingu, jak w 'def unapply (foo: Foo) = Some (() => foo.next)? – Owen

+0

To wydaje się działać. Po prostu unikałem używania 'unapply' dla moich leniwych klas przypadków. W takim przypadku musisz jednak jawnie wywołać funkcję, np. 'Case Foo (n) => Foo (doSomething (n()))'. W tym momencie lepiej użyć "Need". (Jeśli przejdziesz do trasy 'Need', możesz zdefiniować przeciążony konstruktor dla' Foo', który pobiera parametr wywoławczy i zmienia go w 'Need'.) –

Odpowiedz

6

Może ? Zasugerowano mi to w this answer.

scala> case class Foo(next: Name[Foo]) 
defined class Foo 

scala> lazy val x: Foo = Foo(Need(y)); lazy val y: Foo = Foo(Need(x)) 
x: Foo = <lazy> 
y: Foo = <lazy> 

scala> x.next.flatMap(_.next).value eq x 
res61: Boolean = true 
+0

Przypuszczam, że jest dyskusyjne czy to jest odkurzacz. Ale niechlujstwo jest w innym miejscu, więc jest to użyteczna alternatywa w obu kierunkach. – Owen

+0

@Owen, to podejście, do którego uciekłem się w przeszłości. Ja też chciałbym mieć wsparcie w pierwszej klasie. – missingfaktor

Powiązane problemy