হ্যাঁ, যে 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।