Mat*_*han 2 haskell nested list-comprehension
我正在关注这个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)
Run Code Online (Sandbox Code Playgroud)
有一个练习可以找到长度超过 15 的“链”的数量。他们这样做:
numLongChains :: Int
numLongChains = length (filter isLong (map chain [1..100]))
where isLong xs = length xs > 15
Run Code Online (Sandbox Code Playgroud)
我试图提出一个列表理解,而不是给我链的数量,而是给我一个来自 [1..100] 的比 15 长的链列表。到目前为止,我最接近的尝试如下:
[ [ a | a <- chain b, length a > 15] | b <- [1..100]]
Run Code Online (Sandbox Code Playgroud)
但我得到:
<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]
Run Code Online (Sandbox Code Playgroud)
我什至接近吗?尽管可能有更好的方法来解决这个问题,但为了学习,我确实想使用嵌套理解来解决这个问题。
You're close. You're looking for:
[ a | b <- [1..10], let a = chain b, length a > 15 ]
Run Code Online (Sandbox Code Playgroud)
The expression
[ [ a | a <- chain b, length a > 15] | b <- [1..100]]
Run Code Online (Sandbox Code Playgroud)
has type:
Integral [a] => [[[a]]]
Run Code Online (Sandbox Code Playgroud)
which is clearly not what you want, but because of Haskell's polymorphic numeric literals, it could possibly type check if the correct definition were in place.
In this case b is inferred to be a list of some type, and that is why you see the error:
No instance for (Integral [a0]) ...
Run Code Online (Sandbox Code Playgroud)
Here is a complete run down on how the types are inferred.
b <- [1..100] we can infer Enum b is a constraintchain b we can infer Integral b is a constrainta <- chain b we can infer a and b have the same typelength a we can infer a is a list of something, e.g. a ~ [t]因此,从 (3) 和 (4) 我们可以推断出,b ~ [t]因此我们需要Integral [t]和Enum [t]对于某种类型t。
为了进一步详细说明(3),我们知道chain b是一个列表,例如的类型[t]在哪里。从我们知道与 的元素具有相同的类型,即 的类型也是。tba <- chain bachain bat