2012-06-06 20 views
10

Giả sử tôi có một ngu ngốc ít trường hợp lớp như vậy:letrec in Scala? ("? Tie hôn" cách bất di bất dịch để)

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

Làm thế nào tôi có thể xác định ab bất biến mà a.otherbb.othera? Scala có cung cấp cách nào đó cho "tie the knot" không? Tôi muốn làm điều gì đó như thế này:

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

khả năng

Trong Haskell tôi sẽ làm điều này:

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

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

đâu bindings để ab được chứa trong cùng biểu hiện let hoặc ở cấp cao nhất.

Hoặc, không lạm dụng khả năng letrec automagical Haskell của:

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

Lưu ý mô hình lười biếng, ~(a', b'), đó là quan trọng.

+3

Tôi tự hỏi có bao nhiêu công cụ tìm kiếm sẽ bắt đầu tìm kiếm câu hỏi này cho "đám cưới" ... –

+2

Câu hỏi này ít nhiều là một bản sao của http://stackoverflow.com/questions/7507965/instantiating-immutable-paired-objects. Ngoài ra, nếu nó có thể với các trường hợp các lớp 'toString' sẽ recurse mãi mãi –

+0

@LuigiPlinge rằng giải pháp lây nhiễm định nghĩa của lớp chính nó. Tôi muốn thấy một giải pháp mà 'Foo' không được phát hiện. 'toString' thực sự sẽ tái chế vĩnh viễn. –

Trả lời

13

Bạn muốn Foo không thay đổi, nhưng sự lười biếng trong Scala nằm trên trang web khai báo. Không thể Foo không nghiêm ngặt mà không thay đổi và mẫu được chỉ ra trong Haskell chỉ hoạt động vì Foo, ở đó, không nghiêm ngặt (nghĩa là, Foo "a" b không đánh giá ngay b ngay).

Nếu giải pháp này là khá nhiều giống nhau, cho phép các hoops cần thiết để có được tất cả mọi thứ không nghiêm ngặt:

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)) 
+1

Ah bạn nói đúng. Xác định 'dữ liệu Foo = Foo {name ::! String, khác ::! Foo}' làm cho các giải pháp Haskell không hoạt động. –

+0

Cảm ơn nhận xét "nếu không Scala sẽ luôn đánh giá lại". Đó là điều tốt để biết! – Madoc