كلٌّ منا يرث من والديه البيولوجيين مجموعة من التعليمات الكيميائية المعروفة باسم DNA، وهي التي تؤثر في كيفية بناء أجسامنا. تعتمد كل أشكال الحياة المعروفة على DNA!
ملاحظة: لا تحتاج إلى فهم أي شيء عن النيوكليوتيدات أو عن DNA لإكمال هذا التمرين.
يتكوّن DNA من تسلسل طويل من مواد كيميائية أخرى، وأهمّها النيوكليوتيدات الأربعة: الأدينين والسيتوزين والغوانين والثايمين. يمكن أن يحتوي تسلسل DNA واحد على مليارات من هذه النيوكليوتيدات الأربعة، وترتيب ظهورها مهم! نسمّي ترتيب هذه النيوكليوتيدات في جزء من DNA «تسلسل DNA».
نمثّل تسلسل DNA كمجموعة مرتّبة من هذه النيوكليوتيدات الأربعة، والأسلوب الشائع لذلك هو استخدام سلسلة نصية من المحارف مثل «ATTACG» لتسلسل DNA مكوّن من 6 نيوكليوتيدات. حيث 'A' للأدينين، و'C' للسيتوزين، و'G' للغوانين، و'T' للثايمين.
بالنظر إلى سلسلة نصية تمثّل تسلسل DNA، احسب عدد كل نيوكليوتيد موجود فيها. إذا احتوت السلسلة النصية على محارف ليست A أو C أو G أو T، فهي غير صالحة، وعليك الإشارة إلى خطأ.
على سبيل المثال:
"GATTACA" -> 'A': 3, 'C': 1, 'G': 1, 'T': 2
"INVALID" -> error
من الاستخدامات الشائعة لـ Either الإشارة إلى عملية حسابية قد ينتج عنها خطأ (وإذا لم يكن الخطأ الفعلي مهمًا، فقد يكون النوع الأبسط Option خيارًا أفضل). وعند غياب الخطأ تكون النتيجة عادةً Right (للتذكير: القيمة «الصحيحة»)، بينما يكون الخطأ Left، مثل Left[String] الذي يحمل رسالة خطأ. لاحظ أن Either في Scala 2.12 متحيّز إلى اليمين افتراضيًا، لذا يعمل كما هو متوقع مع عمليات مثل filter وmap وflatMap أو داخل for-comprehension. وإذا لم تكن على دراية بـ Either فيمكنك قراءة هذا الدرس التعليمي، لكن انتبه إلى أن هذا الدرس يتناول إصدارات Scala السابقة للإصدار 2.12. أما في Scala 2.12 فيمكنك تجاهل RightProjection وإسقاط .right بأمان. وEither هو ما يُعرف بـ الموناد، وهو يغطي «جانبًا حسابيًا»، وهنا معالجة الأخطاء. والاستخدام الصحيح للمونادات قد يُنتج كودًا موجزًا جدًا مع أنه أنيق ومقروء، أما الاستخدام الخاطئ فقد يؤدي بسهولة إلى العكس. شاهد هذا الفيديو لتتعلّم المزيد.
هناك بعض القواعد العامة لـ Either:
def add1(x: Int): Either[String, Int] = Right(x + 1)
من الأفضل أن تكتب
def add1(x: Int): Int = x + 1
(فهناك Either.map لتطبيق مثل هذه الدوال البسيطة، فلا حاجة إلى إثقالها بـ Either).
isLeft/isRight أو مطابقة الأنماط. فمثلًا، بدلًا منval x: Either[String, Int] = ...
if (x.isRight) x.right.get + 1 else x.left.get
// or
x match {
case Right(n) => n + 1
case Left(s) => s
}
من الأفضل أن تكتب
x fold (identity, _ + 1)
Either. فبدلًا منval xo: Either[String, Int] = ...
val yo: Either[String, Int] = ...
val zo: Either[String, Int] = ...
xo.flatMap(x =>
yo.flatMap(y =>
zo.map(z =>
x + y + z)))
من الأفضل أن تكتب
for {
x <- xo
y <- yo
z <- zo
} yield x + y + z
سجّل في Exercism لتتعلّم وتتقن Scala عبر 95 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.