سؤال

أنا أتعلم هاسكل وأعلق في محاولة لفهم نظام النوع.

أحاول كتابة وظيفة تُرجع طول السلسلة "نصف أو ثلاثة زائد واحد" لإدخال. إليك محاولتي في الوظيفة ، باستخدام نهج متكرر (الوظيفة صالحة للمدخلات المتكاملة فقط):

hotpo :: (Integral a) => a->a
hotpo n = hotpoHelper n 1

hotpoHelper:: (Integral a) => a->a->a
hotpoHelper 1 n = n
hotpoHelper num count
    | even num = hotpoHelper (truncate (num/2)) (count+1)
    | otherwise = hotpoHelper (3*num+1) (count+1)

إليك الخطأ الذي أحصل عليه عندما أحاول تحميل هذا الملف في GHC 6.12.3

test.hs:8:30:
    Could not deduce (RealFrac a) from the context (Integral a)
      arising from a use of `truncate' at test.hs:8:30-45
    Possible fix:
      add (RealFrac a) to the context of
        the type signature for `hotpoHelper'
    In the first argument of `hotpoHelper', namely
        `(truncate (num / 2))'
    In the expression: hotpoHelper (truncate (num / 2)) (count + 1)
    In the definition of `hotpoHelper':
        hotpoHelper num count
                      | even num = hotpoHelper (truncate (num / 2)) (count + 1)
                      | otherwise = hotpoHelper (3 * num + 1) (count + 1)

take (truncate (5/2)) [1,2,3] يعمل ، لذلك أنا غير قادر على فهم رسالة الخطأ هذه. هل أنا على خطأ؟

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

المحلول

ال / يتم استخدام المشغل في Haskell في تقسيم النقطة العائمة. إذا كنت ترغب حقًا في استخدام قسم النقاط العائمة و truncate, ، كنت تستخدم fromIntegral تشغيل num أولا لتحويله إلى رقم نقطة عائم. يقول الخطأ الذي تحصل عليه أنه لا يمكنك استخدام تقسيم الكسور على رقم متكامل (5/2 يعمل لأن المترجم يثبت نوعًا عائمًا لكلا الرقمين). ومع ذلك ، يمكنك أن تفعل ما تريد بسهولة أكبر ، باستخدام div وظيفة. عادة ما يتم استخدام هذا infix ، من خلال المحيط باسم الوظيفة مع backquotes (هذا يعمل مع أي وظيفة haskell):

| even num = hotpoHelper (num `div` 2) (count+1)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top