এর মধ্যে পার্থক্য কী?
উইকিপিডিয়ায়, এই পদগুলি ব্যাখ্যা করার জন্য খুব কম তথ্য এবং কোনও পরিষ্কার কোড নেই।
এই পদগুলি ব্যাখ্যা করে খুব সাধারণ উদাহরণগুলি কী কী?
কোর্সর্সনটি পুনরাবৃত্তির দ্বৈত কীভাবে হয়?
কোন ক্লাসিক কোরকাসিভ অ্যালগরিদম আছে?
এর মধ্যে পার্থক্য কী?
উইকিপিডিয়ায়, এই পদগুলি ব্যাখ্যা করার জন্য খুব কম তথ্য এবং কোনও পরিষ্কার কোড নেই।
এই পদগুলি ব্যাখ্যা করে খুব সাধারণ উদাহরণগুলি কী কী?
কোর্সর্সনটি পুনরাবৃত্তির দ্বৈত কীভাবে হয়?
কোন ক্লাসিক কোরকাসিভ অ্যালগরিদম আছে?
উত্তর:
এটি দেখার অনেকগুলি ভাল উপায় রয়েছে। আমার পক্ষে সবচেয়ে সহজ জিনিসটি "প্ররোচক" এবং "সমন্বয়মূলক সংজ্ঞা" এর মধ্যে সম্পর্ক সম্পর্কে চিন্তা করা
একটি সেট একটি inductive সংজ্ঞা এইভাবে যায়।
"নাট" সেটটিকে ছোটতম সেট হিসাবে সংজ্ঞায়িত করা হয় যে "জিরো" নাট, এবং যদি এন নাট হয় "সুচ এন" নাট হয়।
যা নিম্নলিখিত ওকামেলের সাথে মিলে যায়
type nat = Zero | Succ of nat
এই সংজ্ঞাটি সম্পর্কে একটি বিষয় লক্ষণীয় তা হ'ল একটি সংখ্যা
omega = Succ(omega)
এই সেট এর সদস্য নয়। কেন? অনুমান করুন যে এটি ছিল, এখন সেট এনটিকে বিবেচনা করুন যা নাট হিসাবে ওমেগা না বাদে সমস্ত জাতীয় উপাদান রয়েছে। স্পষ্টতই জিরো N এ, এবং y যদি N এ থাকে তবে Succ (y) N এ থাকে তবে N নাটের চেয়ে ছোট হয় যা একটি বৈপরীত্য। সুতরাং, ওমেগা নেটে নেই।
অথবা, কম্পিউটার বিজ্ঞানীর পক্ষে সম্ভবত আরও দরকারী:
কিছু সেট "ক" দেওয়া, সেট "লিস্ট অফ এ" কে সবচেয়ে ছোট সেট হিসাবে সংজ্ঞায়িত করা হয় যে "নীল" ক এর তালিকায় রয়েছে, এবং যদি x গুলি একটি এবং x এর তালিকায় থাকে তবে "কনস এক্স এক্সস" থাকে এর তালিকায় রয়েছে।
যা কিছু মিলছে something
type 'a list = Nil | Cons of 'a * 'a list
এখানে অপারেটিভ শব্দটি "ক্ষুদ্রতম"। যদি আমরা "ক্ষুদ্রতম" না বলে থাকি তবে সেট নাটে একটি কলা রয়েছে কিনা তা বলার কোনও উপায় আমাদের নেই!
আবার,
zeros = Cons(Zero,zeros)
নাটগুলির তালিকার জন্য একটি বৈধ সংজ্ঞা নয়, ঠিক যেমন ওমেগা বৈধ নাট ছিল না।
ডিফাইনিং তথ্য inductively এই ফাংশন এটি কাজ ব্যবহার নির্ধারণ করতে পারবেন মত পুনরাবৃত্তির
let rec plus a b = match a with
| Zero -> b
| Succ(c) -> let r = plus c b in Succ(r)
এরপরে আমরা এ সম্পর্কিত তথ্য প্রমাণ করতে পারি, যেমন "প্লাস এ জিরো = এ" ইনডাকশন ব্যবহার করে (বিশেষত স্ট্রাকচারাল আনয়ন)
আমাদের প্রমাণটি a তে কাঠামোগত অন্তর্ভুক্তির দ্বারা এগিয়ে যায়।
বেস কেস জন্য একটি জিরো হতে দিন। plus Zero Zero = match Zero with |Zero -> Zero | Succ(c) -> let r = plus c b in Succ(r)
সুতরাং আমরা জানি plus Zero Zero = Zero
। a
এক ঝাঁকুনি হতে দিন । ইন্ডাকটিভ হাইপোথিসিস ধরে নিই plus a Zero = a
। আমরা এখন যে দেখাবেন plus (Succ(a)) Zero = Succ(a)
এই যেহেতু সুস্পষ্ট plus (Succ(a)) Zero = match a with |Zero -> Zero | Succ(a) -> let r = plus a Zero in Succ(r) = let r = a in Succ(r) = Succ(a)
এভাবে আনয়ন দ্বারা plus a Zero = a
সকলের জন্য a
NAT মধ্যে
আমরা অবশ্যই আরও আকর্ষণীয় জিনিস প্রমাণ করতে পারি, তবে এটি সাধারণ ধারণা।
এখন পর্যন্ত আমরা সূক্ষ্মভাবে সংজ্ঞায়িত ডেটা নিয়ে কাজ করেছি যা এটি "ক্ষুদ্রতম" সেট হতে দিয়ে আমরা পেয়েছি। তাই এখন আমরা coinductivly সংজ্ঞায়িত সাথে কাজ করতে চান codata যা আমরা লেট এটা সবচেয়ে বড় সেট হতে দ্বারা পেতে।
সুতরাং
একটি সেট হতে দিন। "স্ট্রিম অফ এ" সেটটিকে বৃহত্তম সেট হিসাবে সংজ্ঞায়িত করা হয় যে এ এর প্রবাহের প্রতিটি এক্সের জন্য এক্স অর্ডারযুক্ত জোড় (মাথা, লেজ) সমন্বিত করে যেমন মাথাটি একটিতে থাকে এবং লেজটি একটি স্রোতে থাকে
হাস্কেলে আমরা এটি প্রকাশ করব
data Stream a = Stream a (Stream a) --"data" not "newtype"
প্রকৃতপক্ষে, হাস্কেলের মধ্যে আমরা সাধারণত অন্তর্নির্মিত তালিকাগুলি ব্যবহার করি যা একটি অর্ডারযুক্ত জোড় বা খালি তালিকা হতে পারে।
data [a] = [] | a:[a]
কলা এই ধরণের কোনও সদস্য নয়, কারণ এটি কোনও অর্ডারযুক্ত জুটি বা খালি তালিকা নয়। তবে, এখন আমরা বলতে পারি
ones = 1:ones
এবং এটি পুরোপুরি বৈধ সংজ্ঞা definition আরও কী, আমরা এই কো-ডেটাতে কো-রিকার্সন করতে পারি। প্রকৃতপক্ষে, কোনও ক্রিয়াকলাপ সহ-পুনরাবৃত্ত এবং পুনরাবৃত্তি হওয়া উভয়ের পক্ষে সম্ভব। যদিও পুনরাবৃত্তিটি একটি ডোমেন সহ ডেটা সমন্বিত ফাংশন দ্বারা সংজ্ঞায়িত করা হয়েছিল , কো-রিকার্সনের অর্থ কেবল এটির একটি সহ-ডোমেন (রেঞ্জও বলা হয়) যা সহ-ডেটা। আদিম পুনরাবৃত্তি বলতে কিছু ক্ষুদ্রতম ডেটা পৌঁছানো পর্যন্ত ছোট ডেটাতে সর্বদা "নিজেকে কল করা" বোঝায় । আপনার আগে যা ছিল তার চেয়ে বড় বা সমান ডেটাতে আদিম সহ-পুনরাবৃত্তি সর্বদা "নিজেকে কল করে"।
ones = 1:ones
আদিম সহ-পুনরাবৃত্তি। ফাংশনটি map
(অত্যাবশ্যক ভাষাগুলির মধ্যে "ফোরচ" এর মতো) উভয়ই আদিম পুনরাবৃত্ত (ধরণের) এবং আদিম সহ-পুনরুক্তিযুক্ত।
map :: (a -> b) -> [a] -> [b]
map f [] = []
map f (x:xs) = (f x):map f xs
একই ফাংশন zipWith
যা একটি ফাংশন এবং তালিকাগুলির এক জোড়া লাগে এবং এই ফাংশনটি ব্যবহার করে তাদের একত্রিত করে for
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith f (a:as) (b:bs) = (f a b):zipWith f as bs
zipWith _ _ _ = [] --base case
ক্রিয়ামূলক ভাষার ক্লাসিক উদাহরণটি হ'ল ফিবোনাচি ক্রম
fib 0 = 0
fib 1 = 1
fib n = (fib (n-1)) + (fib (n-2))
যা আদিম পুনরাবৃত্তিযোগ্য তবে অসীম তালিকা হিসাবে আরও মার্জিতভাবে প্রকাশ করা যেতে পারে
fibs = 0:1:zipWith (+) fibs (tail fibs)
fib' n = fibs !! n --the !! is haskell syntax for index at
অন্তর্ভুক্তি / সমন্বয় একটি আকর্ষণীয় উদাহরণ প্রমাণিত হয় যে এই দুটি সংজ্ঞা একই জিনিস গণনা করে। এটি পাঠকের অনুশীলন হিসাবে ছেড়ে গেছে।
মূলত, কোরকর্সন হ'ল পুনরাবৃত্তি সঞ্চালক -শৈলী , এটির ফলাফলটি প্রারম্ভিক ক্ষেত্রে থেকে এগিয়ে যাওয়ার পথে তৈরি করে, যেখানে নিয়মিত পুনরাবৃত্তি বেস কেস থেকে ফিরে আসার পথে তার ফলাফল তৈরি করে।
(হাস্কেল এখন কথা বলছেন)। এজন্যই foldr
(একটি কঠোর সংমিশ্রণ ফাংশন সহ) পুনরাবৃত্তি প্রকাশ করে এবং foldl'
(কঠোর আঁচড়ায়। চ।) / scanl
/ until
/ iterate
/ unfoldr
/ ইত্যাদি এক্সপ্রেস কর্কর্সন প্রকাশ করে। কোরিয়ার্সন সর্বত্র। foldr
অ-কড়া ঝুঁটি সঙ্গে। চ। লেজ পুনরাবৃত্তি মডুলো কনস প্রকাশ করে ।
এবং Haskell এর পাহারায় পুনরাবৃত্তির ঠিক হয় মত লেজ পুনরাবৃত্তির মডিউল কনস ।
এটি পুনরাবৃত্তি:
fib n | n==0 = 0
| n==1 = 1
| n>1 = fib (n-1) + fib (n-2)
fib n = snd $ g n
where
g n | n==0 = (1,0)
| n>0 = let { (b,a) = g (n-1) } in (b+a,b)
fib n = snd $ foldr (\_ (b,a) -> (b+a,b)) (1,0) [n,n-1..1]
( $
"এর" হিসাবে পড়ুন )। এটি কর্সর্সন:
fib n = g (0,1) 0 n where
g n (a,b) i | i==n = a
| otherwise = g n (b,a+b) (i+1)
fib n = fst.snd $ until ((==n).fst) (\(i,(a,b)) -> (i+1,(b,a+b))) (0,(0,1))
= fst $ foldl (\(a,b) _ -> (b,a+b)) (0,1) [1..n]
= fst $ last $ scanl (\(a,b) _ -> (b,a+b)) (0,1) [1..n]
= fst (fibs!!n) where fibs = scanl (\(a,b) _ -> (b,a+b)) (0,1) [1..]
= fst (fibs!!n) where fibs = iterate (\(a,b) -> (b,a+b)) (0,1)
= (fibs!!n) where fibs = unfoldr (\(a,b) -> Just (a, (b,a+b))) (0,1)
= (fibs!!n) where fibs = 0:1:map (\(a,b)->a+b) (zip fibs $ tail fibs)
= (fibs!!n) where fibs = 0:1:zipWith (+) fibs (tail fibs)
= (fibs!!n) where fibs = 0:scanl (+) 1 fibs
= .....
ভাঁজ: http://en.wikedia.org/wiki/Fold_(higher-order_function)
এই চেক করুন Vitomir Kovanovic এর ব্লগ । আমি এটি পেলাম:
লিস্প, হ্যাস্কেল, পাইথন ইত্যাদির মতো ক্রিয়ামূলক প্রোগ্রামিংয়ের ক্ষমতা সহ প্রোগ্রামিং ভাষায় একটি খুব সুন্দর বৈশিষ্ট্যের অলস মূল্যায়ন পাওয়া যায় It
এর অর্থ হ'ল উদাহরণস্বরূপ আপনি যদি মিলিয়নের উপাদানগুলির একটি তালিকা তৈরি করতে চেয়েছিলেন
(defn x (range 1000000))
তবে এটি আসলে তৈরি করা হয়নি তবে এটি সুনির্দিষ্ট and সেই তালিকার দোভাষী সে তালিকার প্রথম 10 টি উপাদান তৈরি করে। সুতরাং (10 এক্স) নেওয়ার প্রথম রানটি আসলে এই উপাদানগুলি তৈরি করে এবং একই ফাংশনে পরবর্তী সমস্ত কল ইতিমধ্যে বিদ্যমান উপাদানগুলির সাথে কাজ করছে।এটি খুব দরকারী কারণ আপনি মেমরির ত্রুটিগুলি ছাড়াই অসীম তালিকা তৈরি করতে পারেন list তালিকাটি আপনি কতটা অনুরোধ করেছেন ঠিক তত বড় হবে। অবশ্যই, যদি আপনার প্রোগ্রামটি বড় ডেটা সংগ্রহের সাথে কাজ করে তবে এটি এই অসীম তালিকার ব্যবহারে মেমরির সীমাতে আঘাত হানতে পারে।
অন্যদিকে কোরসিয়ার্সনটি পুনরাবৃত্তি হতে দ্বৈত। কি এই মানে? ঠিক যেমন পুনরাবৃত্ত ক্রিয়াকলাপগুলির মতো, যা তাদের শর্তে প্রকাশ করা হয়, কোরস্রুসভ ভেরিয়েবলগুলি নিজের শর্তে প্রকাশ করা হয়।
এটি উদাহরণে সর্বোত্তমভাবে প্রকাশ করা হয়েছে।
ধরা যাক আমরা সমস্ত মৌলিক সংখ্যার তালিকা চাই ...