ओह वाह, यह एक पुराना है! मैं कोड थोड़ा सफाई और वर्तमान मुहावरेदार परंपराओं से लाइन में यह खींच कर शुरू करेंगे:
case class Flat[T, U](fn: T => List[U])
implicit def recFlattenFn[T, U](
implicit f: Flat[T, U] = Flat((xs: T) => List(xs))
) = Flat((xs: List[T]) => xs flatMap f.fn)
def recFlatten[T, U](xs: List[T3])(implicit f: Flat[List[T], U]) = f fn xs
फिर, आगे की हलचल के बिना, कोड को तोड़ने।
case class Flat[T, U](fn: T => List[U])
इस समारोह T => List[U]
के लिए एक नामित आवरण से ज्यादा कुछ नहीं, एक समारोह है कि एक List[U]
का निर्माण करेगा जब प्रकार T
का एक उदाहरण दिया है: सबसे पहले, हम अपने Flat
वर्ग की है। ध्यान दें कि T
यहां List[U]
, या U
, या List[List[List[U]]]
इत्यादि भी हो सकता है। आम तौर पर, ऐसा फ़ंक्शन सीधे पैरामीटर के प्रकार के रूप में निर्दिष्ट किया जा सकता है। लेकिन हम इस मामले का उपयोग प्रत्यारोपण में करने जा रहे हैं, इसलिए नामित रैपर एक निहित संघर्ष के किसी भी जोखिम से बचाता है।
फिर, recFlatten
से पीछे की ओर काम कर रहे:
def recFlatten[T, U](xs: List[T])(implicit f: Flat[List[T], U]) = f fn xs
इस विधि ले जाएगा xs
(एक List[T]
) और यह एक U
में बदलने का। इस लक्ष्य को हासिल करने के लिए, यह तब Flat[T,U]
का एक अंतर्निहित उदाहरण पता लगाता है और संलग्न समारोह का आह्वान, fn
, असली जादू:
implicit def recFlattenFn[T, U](
implicit f: Flat[T, U] = Flat((xs: T) => List(xs))
) = Flat((xs: List[T]) => xs flatMap f.fn)
यह अंतर्निहित recFlatten
द्वारा आवश्यक पैरामीटर को संतुष्ट करता है, यह भी एक और निहित परमाटर लेता है । सबसे महत्वपूर्ण बात:
recFlattenFn
अपनी ही निहित पैरामीटर के रूप में कार्य कर सकते हैं
- यह रिटर्न एक फ्लैट [सूची [X], X], इसलिए
recFlattenFn
केवल परोक्ष का समाधान हो जाएगा के रूप में एक Flat[T,U]
अगर T
एक List
है अंतर्निहित संकल्प विफल रहता है
- निहित
f
एक डिफ़ॉल्ट मान पर वापस आने कर सकते हैं (यानी T
एक List
नहीं है)
Perha ps इस सबसे अच्छा उदाहरण के संदर्भ में समझा जाता है:
recFlatten(List(List(1, 2, 3), List(4, 5)))
- प्रकार
T
List[List[Int]]
के रूप में मान लिया जाता है
- अंतर्निहित देखने के लिए एक `फ्लैट [सूची का प्रयास किया है [सूची [इंट]], यू]
- यह एक के अनुरूप है रिकर्सिवली
recFlattenFn
मोटे तौर पर परिभाषित बोल:
recFlattenFn[List[List[Int]], U] (f =
recFlattenFn[List[Int], U] (f =
Flat[Int,U]((xs: T) => List(xs)) //default value
)
)
ध्यान दें कि recFlattenFn
केवल एक Flat[List[X], X]
के लिए एक अंतर्निहित खोज और प्रकार से मेल खाएगी पैरामीटर [Int,_]
इस मैच असफल क्योंकि Int
एक List
नहीं है। यह वही है जो फॉलबैक को डिफ़ॉल्ट मान पर ट्रिगर करता है।
प्रकार निष्कर्ष यह भी कहा कि संरचना पीछे की ओर काम करता है, प्रत्यावर्तन के प्रत्येक स्तर पर U
परम हल करने:
recFlattenFn[List[List[Int]], Int] (f =
recFlattenFn[List[Int], Int] (f =
Flat[Int,Int]((xs: T) => List(xs)) //default value
)
)
कौन सा बस Flat
उदाहरणों में से एक घोंसले है, हर एक (अंतरतम को छोड़कर) एक flatMap
प्रदर्शन नेस्टेड List
संरचना के एक स्तर को अनलॉक करने के लिए ऑपरेशन। अंतरतम Flat
बस लपेटता सभी अलग-अलग तत्वों एक भी List
में बैक अप।
Q.E.D.
कि एक बहुत मदद करता है धन्यवाद। मुझे लगता है कि आपके उदाहरण में टाइप पैरामीटर एक रैपिंग से बंद हैं। यह 'संकलित recFlatten [सूची [इंट], जे] (सूची (सूची (1, 2, 3), सूची (4, 5))) ( recFlattenFn [सूची [इंट], जे] (च = recFlattenFn [इंट इंट] (च = फ्लैट [इंट इंट] ((XS: इंट) => सूची (XS)) // डिफ़ॉल्ट मान ) ) ) ' – huynhjl
काफी ठीक है, अब अद्यतन :) –