What's wrong with this list comprehension code?

My goal is to list all the elements of the array a

whose values ​​are greater than their index position. I wrote Haskell code like this.



When testing at the ghci prefix prompt, I get the following error message which I cannot understand.

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


source to share

2 answers

Given an expression a!!i

, Haskell will infer that a

is a list (i.e. a::[a]

). Given an expression a<-[1..3]

, Haskell will infer that it a

will have a type Num a => a

(because you are drawing a

from a list of values Num a => a

). While trying to combine these types, Haskell concludes that he a

must have a type Num a => [a]


The bottom line is that it doesn't make sense to think of it a

as a list in one context and as an element from a list of numbers in another context.


I think you could do what you want with something like this:

f xs = map fst . filter (uncurry (>)) $ (xs `zip` [0..])


The expression xs `zip` [0..]

creates a list of pairs, where the first value in each pair is derived from xs

and the second value from [0..]

(an infinite list starting at 0). This serves to associate an index with each value in xs

. The expression uncurry (>)

converts the operator <

into a function acting on pairs. Thus, the expression filter (uncurry (>))

filters the list of pairs only to those elements where the first value is greater than the second. Finally, it map fst

applies the function fst

to each pair of values ​​and returns the result as a list (the function fst

returns the first value in the pair).


Writing meaningless code is fun, so I give you:

f = map snd . filter (uncurry (<)) . zip [0..]




import Data.Maybe
import Control.Monad

f = catMaybes . zipWith (mfilter.(<)) [0..] . map Just


Disclaimer: This code has not been read and may have been made out of judgment. The author has little recollection of what it is about.



All Articles