ما هو الخطأ في تعريفي من الرمز البريدي في هاسكل؟
-
23-09-2019 - |
سؤال
-- eg. myzip [’a’, ’b’, ’c’] [1, 2, 3, 4] -> [(’a’, 1), (’b’, 2), (’c’, 3)]
myzip :: Ord a => [a] -> [a] -> [(a,a)]
myzip list1 list2 = [(x,y) | [x, _] <-list1, [y,_] <-list2 ]
أحصل على رسالة الخطأ هذه:
Occurs check: cannot construct the infinite type: a = [a]
When generalising the type(s) for `myzip'
Failed, modules loaded: none.
المحلول
هناك ثلاث مشاكل: إحداها هي تطابق النمط ، والآخر هو توقيع النوع ، والآخر هو طبيعة فهم القائمة. هنا نسخة مصححة:
{-# LANGUAGE ParallelListComp #-}
myzip :: [a] -> [b] -> [(a, b)]
myzip xs ys = [(x, y) | x <- xs | y <- ys]
- توقيع النوع الأصلي ،
[a] -> [a] -> [(a, a)]
, ، يعني أن كلا القائمتين يجب أن يكونا نفس النوع من العناصر. الOrd a
كان لا لزوم له ، وكان يعني فقط أن أنواع معينة من العناصر قد تم عدم السماح بها. - النمط
[x, _] <- list1
يعني أن كل عنصر من عناصرlist1
يجب أن تكون قائمة عناصر. يستخدمx <- list1
في حين أن. - شمولين القائمة في سلسلة بدلا من التوازي. فكر في الفاصلة كـ "خذ عناصر من List1 ، ثم من List2" (سلسلة). فكر في أنابيب اثنين على أنها موازية.
الفرق بين السلسلة والموازاة:
> [[x, y] | x <- "abc", y <- "123"] -- series
["a1","a2","a3","b1","b2","b3","c1","c2","c3"]
> [[x, y] | x <- "abc" | y <- "123"] -- parallel
["a1","b2","c3"]
نصائح أخرى
إذا قمت بإعادة الكتابة zip
من أجل الحصول على نظرة ثاقبة على Haskell ، أقترح أن تحاول كتابتها دون استخدام شمولية قائمة. تعتبر اختصارات القائمة قوية ، ولكنها تشبه إلى حد ما اختزالًا مناسبًا لبعض الحالات المعينة في Haskell. وكما ترى ، قد يتطلب استخدامها في حالات أخرى امتدادات غير قياسية (مثل ParallelListComp
).
فكر في ماذا zip
يحتاج إلى القيام به في الحالة العامة ، وما يحدث إذا لم يتم الوفاء بالحالة العامة (والتي يمكن أن تحدث بطريقتين!). يجب أن تسقط معادلات الوظيفة بشكل طبيعي.
لا تنتمي إلى StackOverflow