তালিকা রক
হাস্কেলের সিক্যুয়াল ডেটাগুলির জন্য এখন পর্যন্ত সর্বাধিক বন্ধুত্বপূর্ণ ডেটা কাঠামো হ'ল তালিকা
data [a] = a:[a] | []
তালিকাগুলি আপনাকে cons (1) কনস এবং প্যাটার্নের মিল দেয়। মান গ্রন্থাগার, এবং যে প্রস্তাবনা বিষয়টি জন্য, দরকারী তালিকা ফাংশন পূর্ণ যে উচিত আপনার কোড শিবিকা ( foldr
, map
, filter
)। তালিকাগুলি দৃistant় প্রতিরোধী , খাঁটি নিখরচায় কার্যকর, যা খুব সুন্দর। হাস্কেল তালিকাগুলি সত্যিই "তালিকাগুলি" নয় কারণ এগুলি সমন্বিত (অন্যান্য ভাষাগুলি এই স্ট্রিমগুলিকে কল করে) তাই জিনিসগুলি পছন্দ করে
ones :: [Integer]
ones = 1:ones
twos = map (+1) ones
tenTwos = take 10 twos
আশ্চর্য কাজ। অসীম ডেটা স্ট্রাকচার শিলা।
হাস্কেলের তালিকাগুলি অত্যাবশ্যকীয় ভাষাগুলিতে (আলস্যের কারণে) পুনরাবৃত্তির মতো একটি ইন্টারফেস সরবরাহ করে। সুতরাং, এটি উপলব্ধি করে যে তারা ব্যাপকভাবে ব্যবহৃত হয়।
অন্য দিকে
তালিকাগুলির সাথে প্রথম সমস্যাটি হ'ল (!!)
এগুলির মধ্যে সূচী করতে ϴ (কে) সময় লাগে যা বিরক্তিকর। এছাড়াও, সংযোজনগুলি ধীর হতে পারে ++
, তবে হাস্কেলের অলস মূল্যায়ন মডেলটির অর্থ হল যে এগুলি যদি কিছু ঘটে তবে এগুলিকে সম্পূর্ণরূপে স্বতন্ত্র হিসাবে বিবেচনা করা যেতে পারে।
তালিকাগুলি সহ দ্বিতীয় সমস্যাটি হ'ল তাদের কাছে ডেটা লোকাল। যখন মেমরির বস্তুগুলি একে অপরের পাশে স্থাপন না করা হয় তখন প্রকৃত প্রসেসরগুলি উচ্চ ধ্রুবক হিসাবে থাকে। সুতরাং, সি ++ এর std::vector
কাছে আমার জানা বিশুদ্ধ লিঙ্কযুক্ত তালিকার ডেটা কাঠামোর চেয়ে দ্রুত "স্নোক" (শেষে অবজেক্টগুলি স্থাপন করা) রয়েছে, যদিও এটি হাস্কেলের তালিকাগুলির চেয়ে কম বন্ধুত্বপূর্ণ ডেটা কাঠামো নয়।
তালিকাগুলি সহ তৃতীয় সমস্যাটি হ'ল তাদের স্থানের দক্ষতা কম রয়েছে। অতিরিক্ত পয়েন্টারগুলির গোছাগুলি আপনার স্টোরেজটিকে ধ্রুব করে (ধ্রুবক ফ্যাক্টর দ্বারা)।
সিকোয়েন্সগুলি কার্যকরী
Data.Sequence
অভ্যন্তরীণভাবে আঙ্গুলের গাছের উপর ভিত্তি করে (আমি জানি, আপনি এটি জানতে চান না) যার অর্থ তাদের কিছু দুর্দান্ত বৈশিষ্ট্য রয়েছে
- খাঁটি কার্যকর।
Data.Sequence
সম্পূর্ণরূপে প্রতিরোধী ডেটা স্ট্রাকচার।
- গাছের শুরু এবং শেষের দিকে দ্রুত অ্যাক্সেসের ভয় করুন। প্রথম বা শেষ উপাদানটি পেতে বা গাছ সংযোজন করার জন্য ϴ (1) (মোড়িত) জিনিসগুলির তালিকাগুলি দ্রুততম,
Data.Sequence
বেশিরভাগ ধীরে ধীরে ধীর।
- Log (লগ এন) অনুক্রমের মাঝখানে অ্যাক্সেস। এর মধ্যে নতুন সিকোয়েন্সগুলি তৈরি করতে মান সন্নিবেশ অন্তর্ভুক্ত রয়েছে
- উচ্চমানের এপিআই
অন্যদিকে, Data.Sequence
ডেটা লোকালিটি সমস্যার জন্য খুব বেশি কিছু করে না এবং কেবল সীমাবদ্ধ সংগ্রহের জন্য কাজ করে (এটি তালিকার তুলনায় কম অলস)
অ্যারেগুলি মূর্খতার জন্য নয়
অ্যারেগুলি সিএসের অন্যতম গুরুত্বপূর্ণ ডেটা স্ট্রাকচার, তবে অলস বিশুদ্ধ কার্যকরী বিশ্বের সাথে তারা খুব ভাল ফিট করে না। অ্যারে সংগ্রহের মাঝামাঝি সময়ে ϴ (1) অ্যাক্সেস সরবরাহ করে এবং ব্যতিক্রমীভাবে ভাল ডেটার লোকালিয়া / ধ্রুবক কারণগুলি। তবে, যেহেতু তারা হাস্কেলের সাথে খুব ভাল ফিট করে না, তাই তারা ব্যবহারে ব্যথা। বর্তমান স্ট্যান্ডার্ড লাইব্রেরিতে বিভিন্ন ধরণের অ্যারে ধরণের সংখ্যা রয়েছে। এর মধ্যে সম্পূর্ণরূপে ধৈর্যশীল অ্যারে, আইও মোনাডের জন্য পরিবর্তনীয় অ্যারে, এসটি মোনাডের জন্য পরিবর্তনীয় অ্যারে এবং উপরের সংস্করণবিহীন সংস্করণ অন্তর্ভুক্ত রয়েছে। আরও তথ্যের জন্য হ্যাশেল উইকি পরীক্ষা করে দেখুন
ভেক্টর একটি "আরও ভাল" অ্যারে
Data.Vector
প্যাকেজ একটি উচ্চ স্তরের এবং ক্লিনার API এ অ্যারে উদারতা সব না। আপনি কী করছেন তা আপনি যদি না জানেন তবে আপনার যদি পারফরম্যান্সের মতো অ্যারে প্রয়োজন হয় তবে আপনার এগুলি ব্যবহার করা উচিত। অবশ্যই, কিছু সতর্কতামূলক প্রয়োগ এখনও রয়েছে - ডেটা স্ট্রাকচারের মতো পরিবর্তনীয় অ্যারে খাঁটি অলস ভাষায় খুব ভাল খেলেন না। তবুও, কখনও কখনও আপনি যে ও (1) পারফরম্যান্স চান এবং Data.Vector
এটি আপনাকে ব্যবহারযোগ্য প্যাকেজে দেয়।
আপনার কাছে অন্যান্য বিকল্প রয়েছে
আপনি যদি শেষে দক্ষতার সাথে সন্নিবেশ করার ক্ষমতা সহ তালিকাগুলি চান তবে আপনি একটি পার্থক্য তালিকা ব্যবহার করতে পারেন । পারফরম্যান্স স্ক্রু করার তালিকার সেরা উদাহরণটি আসে [Char]
যা থেকে উপস্থাপনাটি আলাদা হয় String
। Char
তালিকাগুলি বিশ্বাসযোগ্য, তবে সি স্ট্রিংয়ের চেয়ে 20 গুণ ধীর গতিতে চালানোর ঝোঁক রয়েছে, তাই নির্দ্বিধায় Data.Text
বা খুব দ্রুত নির্বিঘ্নে অনুভব করুন Data.ByteString
। আমি নিশ্চিত যে অন্যান্য সিকোয়েন্স ভিত্তিক গ্রন্থাগারগুলি আমি এখনই ভাবছি না।
উপসংহার
হাস্কেল তালিকাগুলিতে আমার ক্রমিক সংগ্রহের 90% সময় হ'ল সঠিক ডেটা কাঠামো। তালিকাগুলি পুনরাবৃত্তকারীগুলির মতো হয়, যে ফাংশনগুলি তালিকাগুলি গ্রাহ্য toList
করে তাদের সাথে আসা ফাংশনগুলি ব্যবহার করে সহজেই এই অন্য কোনও ডেটা স্ট্রাকচারের সাথে ব্যবহার করা যেতে পারে। আরও উন্নত বিশ্বে উপস্থাপিকাটি কোন ধরণের কনটেইনার ব্যবহার করে তা সম্পূর্ণ প্যারামিট্রিক হবে তবে বর্তমানে []
এটি স্ট্যান্ডার্ড লাইব্রেরিটি লিটার করে দেয়। সুতরাং, তালিকা (প্রায়) যেখানেই ব্যবহার করা নিশ্চিতভাবেই ঠিক আছে।
আপনি বেশিরভাগ তালিকার ফাংশনগুলির সম্পূর্ণ প্যারামিট্রিক সংস্করণগুলি পেতে পারেন (এবং সেগুলি ব্যবহারে মহৎ)
Prelude.map ---> Prelude.fmap (works for every Functor)
Prelude.foldr/foldl/etc ---> Data.Foldable.foldr/foldl/etc
Prelude.sequence ---> Data.Traversable.sequence
etc
আসলে, Data.Traversable
এমন একটি এপিআই সংজ্ঞায়িত করে যা কোনও কিছুতেই "তালিকান" তালিকায় কম বেশি সর্বজনীন।
তবুও, যদিও আপনি ভাল হতে পারেন এবং কেবলমাত্র প্যারাম্যাট্রিক কোডটি সম্পূর্ণরূপে লিখতে পারেন, আমাদের মধ্যে বেশিরভাগ লোকেরা এই জায়গা জুড়ে নেই এবং ব্যবহার তালিকা। আপনি যদি শিখতে থাকেন তবে আমি আপনাকে দৃ do়রূপে পরামর্শ দিচ্ছি।
সম্পাদনা: মন্তব্যের উপর ভিত্তি করে আমি বুঝতে পারি কখন কখন Data.Vector
বনাম ব্যবহার করব তা আমি কখনই ব্যাখ্যা করি নি Data.Sequence
। অ্যারে এবং ভেক্টরগুলি অত্যন্ত দ্রুত ইনডেক্সিং এবং স্লাইসিং অপারেশন সরবরাহ করে তবে মূলত ক্ষণস্থায়ী (আবশ্যক) ডেটা স্ট্রাকচার। বিশুদ্ধ কার্মিক ডাটা স্ট্রাকচার মত Data.Sequence
এবং []
দক্ষতার উপস্থিত করুক নতুন পুরাতন মান থেকে মান যেন আপনি পুরানো মান পরিবর্তিত করেছিল।
newList oldList = 7 : drop 5 oldList
পুরানো তালিকাটি পরিবর্তন করে না, এবং এটি অনুলিপি করতে হবে না। সুতরাং oldList
অবিশ্বাস্যভাবে দীর্ঘ হলেও , এই "পরিবর্তন" খুব দ্রুত হবে। একভাবে
newSequence newValue oldSequence = Sequence.update 3000 newValue oldSequence
newValue
এর 3000 উপাদানটির জায়গায় একটি সহ একটি নতুন সিক্যুয়েন্স তৈরি করবে । আবার এটি পুরানো ক্রমটি ধ্বংস করে না, এটি কেবল একটি নতুন তৈরি করে। তবে, এটি খুব দক্ষতার সাথে এটি করে, ও (লগ (মিনিট (কে, ন)) গ্রহণ করে যেখানে এন সিকোয়েন্সটির দৈর্ঘ্য, এবং কে হল সূচকটি যা আপনি সংশোধন করেন।
আপনি সহজেই Vectors
এবং এর সাথে এটি করতে পারবেন না Arrays
। এগুলি সংশোধন করা যায় তবে এটি আসল অপরিহার্য পরিবর্তন, এবং তাই নিয়মিত হাস্কেল কোডে করা যায় না। এর অর্থ Vector
প্যাকেজে থাকা ক্রিয়াকলাপগুলি যা পরিবর্তনের মতো করে snoc
এবং cons
পুরো ভেক্টরকে অনুলিপি করতে হয় তাই O(n)
সময় নেয়। এর একমাত্র ব্যতিক্রম হ'ল আপনি মোনাডের (বা ) Vector.Mutable
অভ্যন্তরে পরিবর্তনীয় সংস্করণ ( ) ব্যবহার করতে পারেন এবং আপনার সমস্ত পরিবর্তনগুলি ঠিক যেমন একটি অত্যাবশ্যক ভাষায় করতে পারেন তেমন করতে পারেন । আপনি যখন সম্পন্ন হয়ে যান, আপনি খাঁটি কোডের সাথে ব্যবহার করতে চান এমন পরিবর্তনীয় কাঠামোয় পরিণত করতে আপনি আপনার ভেক্টরকে "হিমায়িত" করেন। ST
IO
আমার অনুভূতিটি হ'ল Data.Sequence
যদি কোনও তালিকা যথাযথ না হয় তবে আপনাকে ডিফল্ট করা উচিত । ব্যবহারের Data.Vector
শুধুমাত্র আপনার ব্যবহারের প্যাটার্ন অনেক পরিবর্তন উপার্জন জড়িত যদি না, অথবা যদি আপনি এসটি / আই monads মধ্যে অত্যন্ত উচ্চ কার্যকারিতা প্রয়োজন।
যদি ST
মোনাদের এই সমস্ত আলোচনা আপনাকে বিভ্রান্ত করে চলেছে: খাঁটি দ্রুত এবং সুন্দরকে আঁকড়ে থাকার আরও আরও কারণ Data.Sequence
।