2012-02-04 10 views
9

निकटतम बातवर्तमान स्काला में, वहाँ "आलसी निर्माता पैटर्न"

case class Foo(lazy next: Foo) 

है कि मैं साथ आने के लिए सक्षम किया गया है करने के लिए एक क्लीनर तरीका

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

मैं पाया जाता है एक सूचीबद्ध समस्या add lazy parameters तो मुझे लगता है कि इसे किसी दिन जोड़ा जाएगा। इस बीच, क्या किसी को उपर्युक्त की तुलना में क्लीनर चाल पता है?

+0

यह उल्लेख है कि अपने 'unapply' विधि आलसी नहीं है, तो पैटर्न की कोशिश कर रहा में एक' Foo' से मेल खाते हैं लायक है एक और 'Foo' में' next' मूल्यांकन किया जा रहा है, जो आप नहीं चाहते हो सकता है परिणाम देगा। –

+0

@BrianMcCutchon यह एक अच्छा मुद्दा है। मुझे लगता है कि इसे आलसी बनाने का एकमात्र तरीका इंडिकेशन जोड़ना होगा, जैसा कि 'def unapply (foo: foo) = कुछ (() => foo.next) '? – Owen

+0

ऐसा लगता है कि काम करता है। मैं सिर्फ अपने आलसी केस वर्गों के लिए 'अनुपयोगी' का उपयोग करने से परहेज कर रहा था। उस स्थिति में, हालांकि, आपको फ़ंक्शन को स्पष्ट रूप से कॉल करने की आवश्यकता है, जैसे 'केस फू (एन) => फू (doSomething (n())) '। उस समय, 'आवश्यकता' का उपयोग करना बेहतर हो सकता है। (साथ ही, यदि आप 'आवश्यकता' मार्ग पर जाते हैं, तो आप 'Foo' के लिए एक अधिभारित कन्स्ट्रक्टर को परिभाषित कर सकते हैं जो कॉल-बाय-नाम पैरामीटर लेता है और उसे' आवश्यकता 'में बदल देता है।) –

उत्तर

6

शायद scalaz.Need? यह मुझे 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

मुझे लगता है कि यह बहस योग्य है या नहीं सफाई वाला। लेकिन गड़बड़ी एक अलग जगह पर है, इसलिए यह एक उपयोगी विकल्प है। – Owen

+0

@ ओवेन, यही वह दृष्टिकोण है जिसे मैंने पहले किया था। मैं भी प्रथम श्रेणी भाषा का समर्थन करना चाहता हूं। – missingfaktor