[英]Nested list comprehensions in Haskell
I am following this Haskell tutorial and am on the higher order functions section. 我正在关注此Haskell教程,并且位于“高阶函数”部分。 It defines a function called chain as: 它定义一个名为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)
There is an exercise to find number of "chains" that have a length longer than 15. They do so like this: 有一项练习来查找长度超过15的“链”的数量。它们的操作如下:
numLongChains :: Int
numLongChains = length (filter isLong (map chain [1..100]))
where isLong xs = length xs > 15
I am trying to come up with a list comprehension that instead of giving me the number of chains gives me a list of chains that are longer than 15 from [1..100]. 我试图提出一个列表理解,而不是给我链的数量,而不是给我一个来自[1..100]的超过15个链的列表。 My closest attempt so far looks like: 到目前为止,我最接近的尝试是:
[ [ a | a <- chain b, length a > 15] | b <- [1..100]]
but I get: 但我得到:
<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]
Am I even close? 我什至靠近吗? I do want to solve this problem using a nested comprehension for the sake of learning despite the possible better ways to approach this. 我确实想通过嵌套理解来解决这个问题,尽管可能有更好的方法来学习。
You're close. 你近了 You're looking for: 您正在寻找:
[ a | b <- [1..10], let a = chain b, length a > 15 ]
The expression 表达方式
[ [ a | a <- chain b, length a > 15] | b <- [1..100]]
has type: 具有类型:
Integral [a] => [[[a]]]
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. 这显然不是您想要的,但是由于Haskell的多态数字文字,它可能可以键入检查是否有正确的定义。
In this case b
is inferred to be a list of some type, and that is why you see the error: 在这种情况下, b
被推断为某种类型的列表,这就是为什么您看到错误的原因:
No instance for (Integral [a0]) ...
Here is a complete run down on how the types are inferred. 这是有关如何推断类型的完整总结。
b <- [1..100]
we can infer Enum b
is a constraint 从b <- [1..100]
我们可以推断Enum b
是一个约束 chain b
we can infer Integral b
is a constraint 从调用chain b
可以推断出Integral b
是一个约束 a <- chain b
we can infer a
and b
have the same type 从a <- chain b
可以推断出a
和b
具有相同的类型 length a
we can infer a
is a list of something, eg a ~ [t]
从length a
我们可以推断出a
是某物的列表,例如a ~ [t]
So from (3) and (4) we can infer that b ~ [t]
and so we need both Integral [t]
and Enum [t]
for some type t
. 因此,从(3)和(4)我们可以推断出b〜 b ~ [t]
,因此对于某些类型t
,我们需要Integral [t]
和Enum [t]
。
To further elaborate on (3), we know chain b
is a list, eg [t]
where t
is the type of b
. 为了进一步阐述(3),我们知道chain b
是一个列表,例如[t]
,其中t
是b
的类型。 From a <- chain b
we know a
has the same type as the elements of chain b
, ie the type of a
is also t
. 从a <- chain b
,我们知道a
具有相同类型的元素chain b
,即类型a
也t
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.