هل أحتاج إلى فهم كيف يمثل Haskell البيانات لتتمكن من كتابة برامج Haskell الجيدة؟

StackOverflow https://stackoverflow.com/questions/3862144

سؤال

أنا أتعلم هاسكل من خلفية جافا. عندما أقوم برمجة Java ، أشعر أن لدي فهمًا قويًا لكيفية وضع الأشياء في الذاكرة وعواقب ذلك. على سبيل المثال ، أعرف بالضبط كيف java.lang.String و java.util.LinkedList العمل وبالتالي أعرف كيف يجب أن أستخدمها. مع هاسكل ، فقدت بعض الشيء. على سبيل المثال ، كيف يفعل (:) الشغل؟ يجب أن أهتم؟ هل تم تحديده في مكان ما؟

هل كانت مفيدة؟

المحلول

الجواب القصير هو لا. عند البرمجة في Haskell ، يجب أن تفكر في هياكل البيانات الخاصة بك ككائنات رياضية خالصة ولا تقلق بشأن كيفية تمثيلها في الذاكرة. والسبب في ذلك هو أنه في غياب الآثار الجانبية ، لا يوجد شيء في الحقيقة إلى البيانات باستثناء الوظائف التي تنشئها والوظائف التي يمكنك استخدامها لاستخراج الأجزاء الأكثر بساطة التي تم إنشاؤها منها.

لمعرفة معلومات حول منشئي البيانات مثل (:), أو أي مصطلحات أخرى ، استخدم :type (أو فقط :t باختصار) أمر داخل GHCI:

:Prelude> :type (:)
(:) :: a -> [a] -> [a]

هذا يخبرك أن (:) المُنشئ (المعلن "Cons") ، يأخذ قيمة لأي نوع ، وقائمة من نفس النوع ، وإرجاع قائمة من نفس النوع. يمكنك أيضًا الحصول على مزيد من المعلومات باستخدام :info يأمر. سيظهر لك هذا كيف يبدو تعريف البيانات:

Prelude> :info (:)
data [] a = ... | a : [a]   -- Defined in GHC.Types
infixr 5 :

هذا يخبرك بذلك (:) هو المُنشئ الذي يعزز عنصرًا إلى قائمة موجودة.

كما أوصي بشدة هوول ليس فقط للنظر في الأشياء بالاسم ولكن للقيام بنوع من البحث العكسي ؛ حيث تعرف توقيع الوظيفة التي تبحث عنها وتريد العثور عليها إذا كان شخص ما قد كتبه بالفعل لك. Hoogle لطيف لأنه يعطي أوصافًا ومثالًا على الاستخدامات.

أشكال البيانات الاستقرائية

قلت أعلاه أنه ليس من المهم معرفة تمثيل بياناتك في الذاكرة ... يجب عليك ، مع ذلك ، أن تفهم شكل من البيانات التي تتعامل معها ، لتجنب قرارات الأداء الضعيفة. يتم تعريف جميع البيانات في Haskell بشكل استقراء ، مما يعني أنه يحتوي على شكل يشبه الأشجار يتكشف عن الخارج بشكل متكرر. يمكنك معرفة شكل البيانات من خلال النظر في تعريفها ؛ لا يوجد شيء مخفي حقًا حول خصائص أدائها بمجرد معرفة كيفية قراءة هذا:

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

كما ترون من التعريف ، فإن الطريقة الوحيدة التي يمكنك الحصول عليها جديدة MyList هو من قبل Cons البناء. إذا كنت تستخدم هذا المُنشئ عدة مرات ، فسوف ينتهي الأمر بشيء من هذا الشكل تقريبًا:

(Cons a5 (Cons a4 (Cons a3 (Cons a2 (Cons a1 Nil)))))

إنها مجرد شجرة بدون فروع ، وهذا هو تعريف القائمة! والطريقة الوحيدة للوصول إلى a1 من خلال تفجير كل من ConsS بدوره ؛ وبالتالي الوصول إلى العنصر الأخير هو على), ، في حين أن الوصول إلى الرأس هو وقت ثابت. بمجرد أن تتمكن من القيام بهذا النوع من التفكير حول هياكل البيانات استنادًا إلى تعريفاتها ، فأنت جميعًا قد تم تعيينك.

نصائح أخرى

الإجابة المختصرة هي "لا" ، لا تحتاج إلى معرفة تخطيطات البيانات - ستكون معرفة التعقيد مفيدة.

لكن لكتابة برامج Haskell المحسّنة للغاية ، فإن معرفة عملية جيدة بشكل هياكل البيانات في الكومة أمر ضروري. أداة لمساعدة هذا "مكنسة", ، والتي يمكن أن تجعل مخططات هياكل بيانات Haskell عند وضعها.

بعض الأمثلة:

$ view "hello"

linked lists

$ view (IntMap.fromList $ zip [1..10] [1..])

Data.IntMap

إليك مقطع فيديو قصير عن كيفية استخدام الأداة: http://www.youtube.com/watch؟v=x4-212umgy8

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top