المسارات
/
Elm
Elm
/
التمارين
/
صندوق الكنز
صندوق الكنز

صندوق الكنز

تمرين تعلّمي

مقدمة

الأنواع العامة

مقدمة

الأنواع العامة ميزة لغوية تتيح إعادة استخدام الكود. على سبيل المثال، لا ينبغي أن يهمنا نوع ما تحمله المصفوفة حتى نحسب طولها. لهذا السبب تستخدم دالة length معامل نوع عام a في توقيع النوع الخاص بها.

length : List a -> Int

المعاملات في الأنواع

عندما يكون نوع ما عامًّا على نوع آخر، نستخدم اسمًا بحروف صغيرة لذلك النوع الآخر، ونسميه معامل نوع. من الأمثلة الشائعة الأنواع المخصصة List وMaybe وResult.

-- Maybe is generic over the type a
type Maybe a
    = Nothing
    | Just a

someString : Maybe String
someString = Just "hello"

someInt : Maybe Int
someInt = Just 42

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

يمكن أن يكون النوع عامًّا على عدة أنواع أخرى، وبالتالي أن يمتلك عدة معاملات نوع. في هذه الحالة، يحصل كل نوع مستقل على اسم مختلف بحروف صغيرة. كون هذه الأنواع مستقلة لا يمنعها من أن تكون النوع نفسه، بل يتيح لها فقط أن تكون مختلفة.

-- Result is generic over the types error and value
type Result error value
    = Ok value
    | Err error

يمكن أن تكون لأسماء أنواع السجلات معاملات نوع أيضًا، وإن كان ذلك أقل شيوعًا.

-- Event is generic over the type a
type alias Event a =
    { at : Time
    , data : a 
    }

معاملات النوع في الدوال

بما أن الأنواع يمكن أن تكون عامة، فكذلك الدوال. يمكن كتابة دوال تتعامل مع أنواع عامة، مثل Maybe.withDefault.

withDefault : a -> Maybe a -> a
withDefault default maybe =
    case maybe of
      Just value -> value
      Nothing -> default

الدوال التي تأخذ دوال أخرى كمعاملات تُسمى الدوال عالية الرتبة، ويمكن أن تكون هذه أيضًا عامة.

map : (a -> b) -> Maybe a -> Maybe b
map function maybe =
  case maybe of
    Just value ->
      Just (function value)

    Nothing ->
      Nothing

التعليمات

في هذا التمرين ستكتب صندوق كنز عامًّا (سحريًّا!) لتخزين بعض الكنوز.

1. عرّف النوع المخصص العام TreasureChest

عرّف نوعًا مخصصًا عامًّا باسم TreasureChest له بديل واحد فقط.

يجب أن يحمل هذا البديل قيمة String مرتبطة به، تُستخدم لتخزين كلمة سر صندوق الكنز.

كما يجب أن يحمل البديل قيمة عامة مرتبطة به، تُستخدم لتخزين الكنز. هذه القيمة عامة، بحيث يمكن أن يكون الكنز أي شيء.

2. عرّف الدالة getTreasure

يجب أن تأخذ هذه الدالة معاملين:

  • قيمة من نوع String (لتجربة كلمة سر)
  • نوعًا مخصصًا عامًّا TreasureChest

يجب أن تتحقق هذه الدالة من محاولة كلمة السر المُعطاة مقابل قيمة String الموجودة في TreasureChest.

يجب أن تُرجع الدالة قيمة Maybe.

إذا تطابقت كلمتا السر، فأرجِع Just مع القيمة العامة الموجودة في TreasureChest (الكنز!).

إذا لم تتطابق كلمتا السر، فأرجِع Nothing.

3. عرّف الدالة multiplyTreasure

يجب أن تأخذ هذه الدالة (عالية الرتبة) معاملين:

  • دالة مُضاعِفة تأخذ معاملًا عامًّا واحدًا، وتُرجع مصفوفة من النوع العام نفسه
  • نوعًا مخصصًا عامًّا TreasureChest، وبالنوع العام نفسه أيضًا

يجب أن تستدعي هذه الدالة الدالة المُضاعِفة مع الكنز الموجود في الصندوق.

يجب أن تُرجع الدالة صندوق كنز جديدًا من نوع TreasureChest، بكلمة السر نفسها التي كانت عليه في الأصل، وبالكنز المضاعَف (القيمة المُرجَعة).

تعديل عبر GitHub يفتح الرابط في نافذة أو علامة تبويب جديدة
Elm Exercism

مستعد لبدء صندوق الكنز؟

سجّل في Exercism لتتعلّم وتتقن Elm عبر 28 مفهومًا110 تمارين، وإرشاد بشري حقيقي، وكل ذلك مجانًا.