هاسكل: مشكلة تحويل نتيجة التقسيم إلى نوع متكامل
سؤال
أنا أتعلم هاسكل وأعلق في محاولة لفهم نظام النوع.
أحاول كتابة وظيفة تُرجع طول السلسلة "نصف أو ثلاثة زائد واحد" لإدخال. إليك محاولتي في الوظيفة ، باستخدام نهج متكرر (الوظيفة صالحة للمدخلات المتكاملة فقط):
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)