প্যারামারফিজম কী?


95

মাধ্যমে পড়া এই ক্লাসিক কাগজ , আমি paramorphisms আটকে করছি। দুর্ভাগ্যক্রমে বিভাগটি বেশ পাতলা, এবং উইকিপিডিয়া পৃষ্ঠাটি কিছুই বলে না।

আমার হাস্কেল অনুবাদটি হ'ল:

para :: (a -> [a] -> b -> b) -> b -> [a] -> b
para f base = h
  where
    h []       =   base
    h (x:xs)   =   f x xs (h xs)

তবে আমি তা ছুঁড়ে দেখি না - টাইপ স্বাক্ষর বা কাঙ্ক্ষিত ফলাফলের জন্য আমার কোনও অনুজ্ঞান নেই।

একটি প্যারামারফিজম কী এবং কার্যক্ষমতার জন্য কয়েকটি দরকারী উদাহরণ কী?


হ্যাঁ, আমি এই প্রশ্নগুলি দেখেছি , তবে এগুলি সরাসরি প্যারামারফিজমগুলি কভার করে না এবং কেবলমাত্র সেই সংস্থানগুলিতে নির্দেশ করে যা রেফারেন্স হিসাবে সহায়ক হতে পারে তবে শেখার উপকরণ হিসাবে নয়।


4
para f base xs = foldr (uncurry f) base $ zip xs (tail $tails xs), methinks।
ড্যানিয়েল ফিশার

এই উইকির পৃষ্ঠা অনুসারে , প্যারামারফিজমগুলি "ইনডাকটিভ ডেটা ধরণের উপরে মডেল আদিম পুনরাবৃত্তি"। এর অর্থ কি কিছু / সহায়তা?
Huon

4
জেরেমি গিবনসের "ফিশন" পত্রিকা যা আমি এই প্রশ্নের একটি মন্তব্যে ইঙ্গিত করেছিলাম তা খুব দরকারী শেখার উপাদান। cs.ox.ac.uk/jeremy.gibbons/publications/fmission.pdf এটি অনেকগুলি পুনরাবৃত্তির নিদর্শনগুলির মধ্যে খুব স্পষ্টভাবে কাজ করে।
স্টিফেন টেটলি

4
ড্যানিয়েল এর পুনরায় লেখা হিসাবে সহজ করা যেতে পারে para f base xs = foldr g base (init $ tails xs) where g (x:xs) = f x xs । এটি কমন লিস্পেরmaplist স্মরণ করিয়ে দেয় ।
নেস

উত্তর:


109

হ্যাঁ, যে 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সংস্করণটি আরও সহজ পাবেন, প্রতিটি নোডের মতো আপনাকে একটি সাবট্রিতে সন্নিবেশ করাতে হবে তবে অন্যটি যেমন ছিল তেমন সংরক্ষণ করতে হবে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.