سؤال
لقد كتبت وظيفة Haskell التي تحسب مصنفة كل رقم في قائمة معينة وتطبعها على الشاشة.
factPrint list =
if null list
then putStrLn ""
else do putStrLn ((show.fact.head) list)
factPrint (tail list)
تعمل الوظيفة ، لكنني أجد السطر الثالث مربكًا بعض الشيء. لماذا لم يبلغ المترجم (GHC) عن خطأ فيه نظرًا لعدم وجود "فعل" قبل وظيفة "putstrln" (شبه؟)؟ إذا حذفت "تفعل" من السطر الرابع ، فإن الخطأ يبرز كما هو متوقع.
أنا جديد تمامًا على Haskell وطرقه ، لذا يرجى العفو عني إذا قلت شيئًا سخيفًا للغاية.
المحلول
do putStrLn ((show.fact.head) list)
factPrint (tail list)
هو في الواقع طريقة أخرى للكتابة
putStrLn ((show.fact.head) list) >> factPrint (tail list)
وهو ما يعني بدوره
putStrLn ((show.fact.head) list) >>= \_ -> factPrint (tail list)
ال do
التدوين هو وسيلة مريحة لتوصيل هذه الموناد معًا ، بدون هذا الجملة القبيحة الأخرى.
إذا كان لديك بيان واحد فقط داخل do
, ، فأنت لا تربط أي شيء معًا ، و do
زائد.
نصائح أخرى
إذا كنت جديدًا على Haskell ، فكر في do
على غرار الأقواس المطلوبة بعد if
في لغة تشبه C:
if (condition)
printf("a"); // braces not required
else {
printf("b"); // braces required
finish();
}
do
يعمل بنفس الطريقة في هاسكل.
ربما سيساعد ذلك في النظر إلى نوع الحقائق ، ثم Refactor لاستخدام مطابقة الأنماط:
factPrint :: [Int] -> IO ()
factPrint [] = putStrLn ""
factPrint list = do
putStrLn (show.fact.head) list
factPrint (tail list)
لذلك ، إذا عادت الحقائق IO ()
, ، ونوع putStrLn ""
هو IO ()
, ، ثم من القانوني تمامًا factPrint []
لتساوي putStrLn ""
. رقم do
مطلوب-في الواقع ، يمكنك القول فقط factPrint [] = return ()
إذا كنت لا تريد خط جديد.
do
يستخدم لربط تعبيرات أحادية متعددة معا. ليس له أي تأثير عندما يتبعه تعبير واحد فقط.
من أجل أن تكون جيدًا ، فمن الضروري فقط أن يكون للباقي والباقي الآخر نفس النوع. لأن كلا الجملتين لهما النوع IO ()
هذا هو الحال.
يتم استخدام الكلمة الرئيسية DO للتسلسل ، لا يجب أن تحتوي على if-then-else في Haskell do
على الإطلاق إذا كان كل فرع عبارة عن بيان واحد على سبيل المثال.
if a
then b
else c
أنت بحاجة إلى do
في المثال الخاص بك وأنت تتسلسل عمليتين على فرع آخر. إذا حذفت do
ثم factPrint(tail list)
يعتبر البيان جزءًا من الوظيفة ، وبالتالي يشكو المترجم لأنه واجه بيانًا غير متوقع.