这个列表理解代码有什么问题?

sur*_*esh 3 haskell

我的目标是列出数组a的所有元素,这些元素的值大于它们的索引位置.我写了一个像这样的Haskell代码.

[a|i<-[0..2],a<-[1..3],a!!i>i]
Run Code Online (Sandbox Code Playgroud)

在ghci prelude提示符上测试时,我收到以下错误消息,我无法理解.

No instance for (Num [a]) arising from the literal 3 at <interactive>:1:20 Possible fix: add an instance declaration for (Num [a])

Dan*_*att 10

鉴于表达式a!!i,Haskell将推断这a是一个列表(即a::[a]).给定表达式a<-[1..3],Haskell将推断a将具有类型Num a => a(因为您aNum a => a值列表中绘制).试图统一这些类型,Haskell得出结论,a实际上必须是类型Num a => [a].

最重要的是,a在一个上下文中将其视为一个列表,在另一个上下文中作为一个数字列表中的元素是没有意义的.

编辑

我想你可以用这样的东西做你想做的事:

f xs = map fst . filter (uncurry (>)) $ (xs `zip` [0..])
Run Code Online (Sandbox Code Playgroud)

表达式xs `zip` [0..]创建一个对列表,其中每对中的第一个值是从中抽取的xs,第二个值来自[0..](从0开始的无限列表).这用于将索引与每个值相关联xs.表达式uncurry (>)<运算符转换为对的函数.因此,表达式filter (uncurry (>))仅将对列表过滤到第一个值大于第二个值的元素.最后,map fstfst函数应用于每对值并将结果作为列表fst返回(函数返回一对的第一个值).

编辑2

编写无意义的代码很有趣,所以我给你:

f = map snd . filter (uncurry (<)) . zip [0..]
Run Code Online (Sandbox Code Playgroud)

  • @suresh:如果你更喜欢列表推导,请使用`[x | (i,x)< - zip [0 ..] xs,x> i]`.我认为这比上面的解决方案略显清晰. (5认同)
  • 如何纠正它取决于您对此代码的意图. (3认同)