হ্যাঁ, যে para। ক্যাটমোরফিজমের সাথে তুলনা করুন, বা foldr:
para :: (a -> [a] -> b -> b) -> b -> [a] -> b
foldr :: (a -> b -> b) -> b -> [a] -> b
para c n (x : xs) = c x xs (para c n xs)
foldr c n (x : xs) = c x (foldr c n xs)
para c n [] = n
foldr c n [] = n
কিছু লোক প্যারাওরফিজমকে "আদিম পুনরাবৃত্তি" বলে বিবর্তন করে ক্যাটামোরফিজমগুলির ( foldr")" পুনরাবৃত্তি "বলে contrast
যেখানে foldrদুটি পরামিতি ইনপুট ডেটার প্রতিটি পুনরাবৃত্ত সাববোজেক্টের জন্য পুনরাবৃত্তভাবে গণনা করা মান দেওয়া হয় (এখানে, এটি তালিকার পুচ্ছ), paraএর পরামিতিগুলি মূল সাবোবজেক্ট এবং মান উভয় থেকেই এটিকে পুনরাবৃত্তভাবে গণনা করে।
একটি উদাহরণ ফাংশন যা সুন্দরভাবে প্রকাশ করা paraহয় তা হ'ল তালিকার যথাযথ ওষুধের সংগ্রহ।
suff :: [x] -> [[x]]
suff = para (\ x xs suffxs -> xs : suffxs) []
যাতে
suff "suffix" = ["uffix", "ffix", "fix", "ix", "x", ""]
সম্ভবত এখনও সহজ
safeTail :: [x] -> Maybe [x]
safeTail = para (\ _ xs _ -> Just xs) Nothing
যাতে "কনস" শাখাটি তার পুনরাবৃত্তভাবে গণনা করা যুক্তি উপেক্ষা করে এবং লেজটি ফিরিয়ে দেয়। অলসভাবে মূল্যায়ন করা হয়, পুনরাবৃত্তিমূলক গণনা কখনই হয় না এবং ধ্রুবক সময়ে লেজ বের করা হয়।
আপনি বেশ সহজেই foldrব্যবহার করে সংজ্ঞা দিতে paraপারেন; এটি থেকে সংজ্ঞা paraদেওয়া একটু কৌশলযুক্ত foldr, তবে এটি অবশ্যই সম্ভব এবং এটি কীভাবে হয়েছিল তা প্রত্যেকেরই জানা উচিত!
foldr c n = para (\ x xs t -> c x t) n
para c n = snd . foldr (\ x (xs, t) -> (x : xs, c x xs t)) ([], n)
সংজ্ঞা থেকে কৌতুক paraসঙ্গে foldrএকটি পুনর্গঠন হয় কপি মূল তথ্য যাতে আমরা প্রতিটি পদক্ষেপ এ লেজ একটি কপি অ্যাক্সেস লাভ, যদিও আমরা আসল কোন অ্যাক্সেস ছিল। শেষে, sndইনপুটটির অনুলিপি বাতিল করে দেয় এবং কেবল আউটপুট মান দেয়। এটি খুব দক্ষ নয়, তবে আপনি যদি নিছক ভাবের প্রতি আগ্রহী হন paraতবে আপনাকে এর চেয়ে বেশি কিছু দেয় না foldr। আপনি এই ব্যবহার করেন তাহলে foldrএর -encoded সংস্করণ para, তারপর safeTailসব পরে রৈখিক সময় লাগবে, উপাদান দ্বারা লেজ উপাদান অনুলিপি করা হবে।
সুতরাং, এটি paraহ'ল : এটি একটি আরও সুবিধাজনক সংস্করণ foldrযা এর সাহায্যে তালিকার লেজটিতে তাত্ক্ষণিক অ্যাক্সেসের পাশাপাশি এটির থেকে গুণিত মান দেয় gives
সাধারণ ক্ষেত্রে, কোনও ফান্টারের পুনরাবৃত্তি ফিক্সপয়েন্ট হিসাবে উত্পন্ন ডেটাটাইপের সাথে কাজ করা
data Fix f = In (f (Fix f))
তোমার আছে
cata :: Functor f => (f t -> t) -> Fix f -> t
para :: Functor f => (f (Fix f, t) -> t) -> Fix f -> t
cata phi (In ff) = phi (fmap (cata phi) ff)
para psi (In ff) = psi (fmap keepCopy ff) where
keepCopy x = (x, para psi x)
এবং আবার, দু'টি পারস্পরিক সংজ্ঞাযুক্ত, একই "অনুলিপি তৈরি করুন" কৌশল দ্বারা paraসংজ্ঞায়িতcata
para psi = snd . cata (\ fxt -> (In (fmap fst fxt), psi fxt))
আবার, এর paraচেয়ে আর কোনও ভাবগত নয়, cataতবে আপনার যদি ইনপুটটির কাঠামোগুলিগুলিতে সহজে অ্যাক্সেসের প্রয়োজন হয়।
সম্পাদনা: আমার আর একটি চমৎকার উদাহরণ মনে পড়ে গেল।
Fix TreeFকোথায় দেওয়া বাইনারি অনুসন্ধান গাছগুলি বিবেচনা করুন
data TreeF sub = Leaf | Node sub Integer sub
এবং বাইনারি অনুসন্ধান গাছগুলির জন্য সন্নিবেশ সংজ্ঞায়িত করার চেষ্টা করুন, প্রথমে একটি হিসাবে cata, তারপরে একটি হিসাবে para। আপনি paraসংস্করণটি আরও সহজ পাবেন, প্রতিটি নোডের মতো আপনাকে একটি সাবট্রিতে সন্নিবেশ করাতে হবে তবে অন্যটি যেমন ছিল তেমন সংরক্ষণ করতে হবে।
para f base xs = foldr (uncurry f) base $ zip xs (tail $tails xs), methinks।