কীভাবে 'বনভূমি' একটি প্রোগ্রাম থেকে 'গাছ' মুছে ফেলবে?


12

আমি মনে করি কীভাবে বনভূমি একই সাথে গ্রাহ্য করে এবং একটি তালিকা উত্পাদন করে (একটি ভাঁজ এবং একটি উদ্ঘাটন ফাংশন থেকে - কোডেরউভিউতে এই ভাল উত্তরটি দেখুন এখানে ), কিন্তু যখন আমি সেই প্রযুক্তিটিতে উইকিপিডিয়া এন্ট্রিটির সাথে তুলনা করি তখন এটি 'অপসারণের বিষয়ে' কথা বলেছিল গাছ 'একটি প্রোগ্রাম থেকে।

আমি বুঝতে পারি যে কোনও প্রোগ্রামকে কীভাবে সিন্ট্যাকটিক পার্স গাছের মধ্যে পার্স করা যায় (এটি কি সঠিক?), তবে প্রোগ্রামগুলির একধরণের সরলীকরণের জন্য এটি কী (বন?) ব্যবহারের অর্থ কী? এবং আমি কীভাবে আমার কোডটিতে এটি করব?

উত্তর:


9

ইয়তিমা 2975 আপনার প্রথম দুটি প্রশ্ন কভার করেছে বলে মনে হচ্ছে, আমি তৃতীয়টি কভার করার চেষ্টা করব। এটি করার জন্য আমি একটি অবাস্তববাদী সহজ মামলার চিকিত্সা করব তবে আমি নিশ্চিত আপনি আরও বাস্তবের কিছু কল্পনা করতে সক্ষম হবেন।

n

type Tree = Leaf | Node Tree Tree

n

full : Int -> Tree
full n | n == 0 = Leaf
full n = Node (full (n-1)) (full (n-1))

এবং একটি গাছ গভীরতা দ্বারা গণনা করা হয়

depth : Tree -> Int
depth Leaf = 0
depth (Node t1 t2) = 1 + max (depth t1) (depth t2)

depth (full n)nfulldepthdepth (full n)full_depth

full_depth : Int -> Int
full_depth n | n == 0 = 0
full_depth n = 1 + max (full_depth (n-1)) (full_depth (n-1))

এটি সম্পূর্ণ গাছের মেমরি বরাদ্দ এবং এটিকে প্যাটার্ন ম্যাচিংয়ের প্রয়োজনীয়তা এড়িয়ে যায়, যা কার্য সম্পাদনকে ব্যাপকভাবে উন্নত করে। এছাড়াও, আপনি অপ্টিমাইজেশন যোগ করুন

max t t --> t

full_depth

কেবলমাত্র মূলধারার সংকলক যা স্বয়ংক্রিয়ভাবে বন কাটা সম্পাদন করে তা হ'ল জিএইচসি, এবং যদি আমি সঠিকভাবে স্মরণ করি তবে বিল্ট-ইন ফাংশন (প্রযুক্তিগত কারণে) রচনা করার সময় এটি সম্পাদন করা হয় ।


পুরষ্কার দেওয়া হয়েছে কারণ অন্য উত্তরগুলির চেয়ে এটি যেভাবে তৈরি করা হয়েছিল সেভাবেই আমি উত্তরটি আরও বেশি পেয়েছি, যদিও তারা মূলত একই অঞ্চলটি আবৃত করে।
ক্রিস স্ট্রিংফেলো

6

প্রথমত, তালিকাগুলি এক ধরণের গাছ। যদি আমরা লিঙ্কযুক্ত তালিকা হিসাবে একটি তালিকা উপস্থাপন করি তবে এটি কেবলমাত্র এমন একটি গাছ যার প্রতিটি নোডে হয় 1 বা 0 বংশধর।

পার্স গাছগুলি ডেটা কাঠামো হিসাবে গাছের কেবলমাত্র ব্যবহার। কম্পিউটার বিজ্ঞানে গাছগুলিতে অনেকগুলি অ্যাপ্লিকেশন রয়েছে যার মধ্যে বাছাই করা, মানচিত্র প্রয়োগ করা, সহযোগী অ্যারে ইত্যাদি রয়েছে including

সাধারণভাবে, তালিকা, গাছ ইত্যাদি পুনরাবৃত্ত তথ্য কাঠামো: প্রতিটি নোডে কিছু তথ্য এবং একই ডেটা কাঠামোর অন্য একটি উদাহরণ রয়েছে। ভাঁজ হ'ল এ জাতীয় সমস্ত কাঠামোর উপর একটি ক্রিয়া যা পুনরাবৃত্তভাবে নোডগুলিকে "নীচে আপ" মানগুলিতে রূপান্তর করে। আনফোল্ডিং হ'ল বিপরীত প্রক্রিয়া, এটি মানগুলি "টপ ডাউন" তে রূপান্তর করে।

প্রদত্ত ডেটা স্ট্রাকচারের জন্য, আমরা যান্ত্রিকভাবে তাদের ভাঁজ এবং ফোল্ডিং ফাংশনগুলি তৈরি করতে পারি।

উদাহরণ হিসাবে, আসুন তালিকাগুলি নেওয়া যাক। (আমি উদাহরণস্বরূপ হ্যাস্কেলকে এটি টাইপ করার সাথে ব্যবহার করব এবং এর বাক্য গঠনটি খুব পরিষ্কার)) তালিকাটি হয় শেষ বা মান এবং একটি "লেজ"।

data List a = Nil | Cons a (List a)

এখন কল্পনা করুন আমরা একটি তালিকা ভাঁজ করছি। প্রতিটি পদক্ষেপে, আমাদের বর্তমান নোডটি ভাঁজ করতে হবে এবং ইতিমধ্যে আমরা এর পুনরাবৃত্ত সাব-নোডগুলি ভাঁজ করেছি। আমরা এই রাষ্ট্র হিসাবে প্রতিনিধিত্ব করতে পারেন

data ListF a r = NilF | ConsF a r

rসাবলিস্টটি ভাঁজ করে মধ্যবর্তী মানটি কোথায় তৈরি করা হয়? এটি আমাদের তালিকাগুলিতে একটি ভাঁজ ফাংশন প্রকাশ করতে দেয়:

foldList :: (ListF a r -> r) -> List a -> r
foldList f Nil            = f NilF
foldList f (Cons x xs)    = f (ConsF x (foldList f xs))

আমরা রূপান্তর Listমধ্যে ListFযাও recursively তার sublist উপর ভাঁজ এবং তারপর একটি ফাংশন সংজ্ঞাসমূহ ব্যবহার ListF। আপনি যদি এটির বিষয়ে চিন্তা করেন তবে এটি স্ট্যান্ডার্ডের আরও একটি উপস্থাপনা foldr:

foldr :: (a -> r -> r) -> r -> List a -> r
foldr f z = foldList g
  where
    g NilF          = z
    g (ConsF x r)   = f x r

আমরা unfoldListএকই ফ্যাশনে তৈরি করতে পারি:

unfoldList :: (r -> ListF a r) -> r -> List a
unfoldList f r = case f r of
                  NilF        -> Nil
                  ConsF x r'  -> Cons x (unfoldList f r')

আবার এটির আর একটি উপস্থাপনা unfoldr:

unfoldr :: (r -> Maybe (a, r)) -> r -> [a]

(লক্ষ্য করুন যে Maybe (a, r)এটি isomorphic ListF a r।)

এবং আমরা বনাঞ্চলের ফাংশনও তৈরি করতে পারি:

deforest :: (ListF a r -> r) -> (s -> ListF a s) -> s -> r
deforest f u s = f (map (deforest f u) (u s))
  where
    map h NilF        = NilF
    map h (ConsF x r) = ConsF x (h r)

এটি কেবল মধ্যবর্তীটি ছেড়ে দেয় Listএবং ভাঁজ এবং ফোল্ডিং ফাংশনগুলি একসাথে ফিউজ করে।

একই পদ্ধতিটি কোনও পুনরাবৃত্ত তথ্য কাঠামোতে প্রয়োগ করা যেতে পারে। উদাহরণস্বরূপ, একটি গাছ যার নোডে 0, 1, 2 বা 1- বা 0-ব্রাঞ্চিং নোডের মান সহ বংশধর থাকতে পারে:

data Tree a = Bin (Tree a) (Tree a) | Un a (Tree a) | Leaf a

data TreeF a r = BinF r r | UnF a r | LeafF a

treeFold :: (TreeF a r -> r) -> Tree a -> r
treeFold f (Leaf x)       = f (LeafF x)
treeFold f (Un x r)       = f (UnF x (treeFold f r))
treeFold f (Bin r1 r2)    = f (BinF (treeFold f r1) (treeFold f r2))

treeUnfold :: (r -> TreeF a r) -> r -> Tree a
treeUnfold f r = case f r of
                  LeafF x         -> Leaf x
                  UnF x r         -> Un x (treeUnfold f r)
                  BinF r1 r2      -> Bin (treeUnfold f r1) (treeUnfold f r2)

অবশ্যই আমরা deforestTreeআগের মতো যান্ত্রিকভাবে তৈরি করতে পারি ।

(সাধারণত, আমরা treeFoldআরও স্বাচ্ছন্দ্যের সাথে এর মতো প্রকাশ করতে চাই :

treeFold' :: (r -> r -> r) -> (a -> r -> r) -> (a -> r) -> Tree a -> r

)

আমি বিশদটি ছেড়ে দেব, আমি আশা করি প্যাটার্নটি সুস্পষ্ট।

আরো দেখুন:


দুর্দান্ত উত্তর, ধন্যবাদ। লিঙ্কগুলি এবং বিস্তারিত উদাহরণ মূল্যবান।
ক্রিস স্ট্রিংফেলো

3

এটি কিছুটা বিভ্রান্তিকর, তবে মধ্যবর্তী গাছগুলি তৈরি করার জন্য (রান সময়) বনাঞ্চল প্রয়োগ করা হয়েছে (সংকলনের সময়)। বন উজানে বিমূর্ত সিনট্যাক্স গাছের কিছু অংশ হ্যাক করা জড়িত না (এটি মৃত শাখা নির্মূল :-)

আরেকটা জিনিস আপনি বন্ধ নিক্ষিপ্ত করে রাখলে তা তালিকা হয় হয় গাছ শুধু খুব ভারসাম্যহীন বেশী,!


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