Reputation: 1109
My aim is to list all elements of the array a
whose values are greater than their index positions. I wrote a Haskell code like this.
[a|i<-[0..2],a<-[1..3],a!!i>i]
When tested on ghci prelude prompt, I get the following error message which I am unable to understand.
No instance for (Num [a]) arising from the literal 3 at <interactive>:1:20 Possible fix: add an instance declaration for (Num [a])
Upvotes: 3
Views: 414
Reputation: 54574
import Data.Maybe
import Control.Monad
f = catMaybes . zipWith (mfilter.(<)) [0..] . map Just
Disclaimer: The given code was not proof read and may have been made outside of sobriety. The author has little recollection of what it is about.
Upvotes: 1
Reputation: 12077
Given the expression a!!i
, Haskell will infer that a
is a list (i.e. a::[a]
). Given the expression a<-[1..3]
, Haskell will infer that a
will have type Num a => a
(because you are drawing a
from a list of Num a => a
values). Trying to unify these types, Haskell concludes that a
must actually be of type Num a => [a]
.
The bottom line is that it doesn't make sense to treat a
as a list in one context and as an element from a list of numbers in another context.
EDIT
I'm thinking 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 drawn from xs
and the second value from [0..]
(an infinite list starting from 0). This serves to associate an index to each value in xs
. The expression uncurry (>)
converts the <
operator into a function that works on pairs. So the expression filter (uncurry (>))
filters a list of pairs to only those elements where the first value is greater than the second. Finally, map fst
applies the fst
function to each pair of values and returns the result as a list (the fst
function returns the first value of a pair).
EDIT 2
Writing pointless code is fun, and so I give you:
f = map snd . filter (uncurry (<)) . zip [0..]
Upvotes: 10