में बदला जा सकता यह अक्सर उपयोगी, विशेष रूप से कई निर्माताओं के साथ पुनरावर्ती डेटा प्रकार के लिए है , कैटमोर्फिज्म को परिभाषित करने के लिए, प्रत्येक संभावित रचनाकारों के लिए एक फ़ंक्शन दिए जाने पर डेटा संरचना को फोल्ड करने का एक तरीका।
उदाहरण के लिए, Bool
के लिए catamorphism
bool :: a -> a -> Bool -> a
bool x _ False = x
bool _ y True = y
है और Either
के लिए यह
either :: (a -> c) -> (b -> c) -> Either a b -> c
either f g (Left x) = f x
either f g (Right x) = g x
एक और अधिक उन्नत catamorphism सूचियों के लिए एक है, जो आप शायद पहले देखा है है: foldr
!
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr f init [] = init
foldr f init (x:xs) = f x (foldr f init xs)
हम नहीं आमतौर पर इस तरह से (या कम से कम मैं नहीं) इसके बारे में सोचते हैं, लेकिन foldr
एक catamorphism है: यह, पैटर्न मिलान संभालती है और आप के रूप में इतने लंबे समय के रिकर्सिवली आप के लिए सूची deconstructing [a]
के दो निर्माताओं में पाया मूल्यों के लिए "संचालकों" प्रदान करते हैं:
- ही एक मामला
[]
को संभालने के लिए, कोई तर्क बिल्कुल की जरूरत: बस प्रकार b
- ही एक मामला
(x:xs)
संभाल करने के एक मूल्य। इस मामले में x
का प्रतिनिधित्व करने वाला एक तर्क होता है, जो सूची का प्रमुख होता है, और एक तर्क जो पूंछ को फिर से फोल्ड करने के परिणाम का प्रतिनिधित्व करता है, b
का मान।
एक catamorphism केवल एक निर्माता के साथ एक प्रकार के लिए कम रोमांचक है, लेकिन हम आसानी से अपने Keypress
प्रकार के लिए एक परिभाषित कर सकते हैं:
key :: (Int -> Char -> a) -> Keypress -> a
key f (Keypress x c) = f x c
एक तरह से, catamorphism दूर सार पैटर्न के लिए आप की अनुमति देता है फ़ंक्शन परिभाषा का मिलान करने के बाद, जिसके बाद आप केवल उन कार्यों के साथ काम कर सकते हैं जिन्हें अंतर्निहित डेटा प्रकार को सीधे स्पर्श करने की आवश्यकता नहीं है।
यह परिभाषित करने के बाद कि आम तौर पर एक बार उपयोगी काम होता है, आप अपने दिल की इच्छाओं के किसी भी बिंदु-मुक्त कार्य को लागू करने के लिए इसे कई बार उपयोग कर सकते हैं। आपके मामले में, आप बस
getSeq :: Keypress -> [Char]
getSeq = key replicate
लिख सकते हैं