[英]Nested list comprehensions in Haskell
我正在關注此Haskell教程,並且位於“高階函數”部分。 它定義一個名為chain的函數為:
chain :: (Integral a) => a -> [a]
chain 1 = [1]
chain n
| even n = n:chain (n `div` 2)
| odd n = n:chain (n * 3 + 1)
有一項練習來查找長度超過15的“鏈”的數量。它們的操作如下:
numLongChains :: Int
numLongChains = length (filter isLong (map chain [1..100]))
where isLong xs = length xs > 15
我試圖提出一個列表理解,而不是給我鏈的數量,而不是給我一個來自[1..100]的超過15個鏈的列表。 到目前為止,我最接近的嘗試是:
[ [ a | a <- chain b, length a > 15] | b <- [1..100]]
但我得到:
<interactive>:9:14:
No instance for (Integral [a0]) arising from a use of `chain'
Possible fix: add an instance declaration for (Integral [a0])
In the expression: chain b
In a stmt of a list comprehension: a <- chain b
In the expression: [a | a <- chain b, length a > 15]
<interactive>:9:45:
No instance for (Enum [a0])
arising from the arithmetic sequence `1 .. 100'
Possible fix: add an instance declaration for (Enum [a0])
In the expression: [1 .. 100]
In a stmt of a list comprehension: b <- [1 .. 100]
In the expression:
[[a | a <- chain b, length a > 15] | b <- [1 .. 100]]
<interactive>:9:46:
No instance for (Num [a0]) arising from the literal `1'
Possible fix: add an instance declaration for (Num [a0])
In the expression: 1
In the expression: [1 .. 100]
In a stmt of a list comprehension: b <- [1 .. 100]
我什至靠近嗎? 我確實想通過嵌套理解來解決這個問題,盡管可能有更好的方法來學習。
你近了 您正在尋找:
[ a | b <- [1..10], let a = chain b, length a > 15 ]
表達方式
[ [ a | a <- chain b, length a > 15] | b <- [1..100]]
具有類型:
Integral [a] => [[[a]]]
這顯然不是您想要的,但是由於Haskell的多態數字文字,它可能可以鍵入檢查是否有正確的定義。
在這種情況下, b
被推斷為某種類型的列表,這就是為什么您看到錯誤的原因:
No instance for (Integral [a0]) ...
這是有關如何推斷類型的完整總結。
b <- [1..100]
我們可以推斷Enum b
是一個約束 chain b
可以推斷出Integral b
是一個約束 a <- chain b
可以推斷出a
和b
具有相同的類型 length a
我們可以推斷出a
是某物的列表,例如a ~ [t]
因此,從(3)和(4)我們可以推斷出b〜 b ~ [t]
,因此對於某些類型t
,我們需要Integral [t]
和Enum [t]
。
為了進一步闡述(3),我們知道chain b
是一個列表,例如[t]
,其中t
是b
的類型。 從a <- chain b
,我們知道a
具有相同類型的元素chain b
,即類型a
也t
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.