Reputation: 1437
I want to write a function that takes a number i
and a list of numbers xs
and
returns the position of i
in the list xs
, counting the first position as 1. If i
does
not occur in xs
, then position
returns 0.
So far I have this:
import Data.List
position :: Int -> [Int] -> Int
position i xs
| i `elem` xs = i `elemIndex` xs
| otherwise = 0
But when I compile, it gives the following error:
Couldn't match expected type ‘Int’ with actual type ‘Maybe Int’
I know that elemIndex
returns a Maybe Int
type and I defined my function to return Int
but I don't know how to change it. Any ideas?
Upvotes: 4
Views: 23488
Reputation: 82
You could even use the zip function in the standard prelude of haskell :) Just zip it with [1..] and then use the list comprehension provided by it. Check out the code here:
positions n xs = [y | (y,z) <- zip [1..] xs, z==n]
To find the number of occurences, just use length from the standard prelude:
positions n xs = length [y | (y,z) <- zip [1..] xs, z==n]
Upvotes: 1
Reputation: 1568
I think, the solution above could be one-liner using the maybe
function:
import Data.List
position :: Eq a => a -> [a] -> Int
position i xs = maybe 0 (+1) $ i `elemIndex` xs
Upvotes: 6
Reputation: 105985
First of all, lists are indexed with 0…
. So elemIndex
will return Just 0
if i
happens to be the first element of your list.
Since elemIndex
returns Maybe Int
, you could pattern match on its result instead:
import Data.List (elemIndex)
position :: Eq a => a -> [a] -> Int
position i xs =
case i `elemIndex` xs of
Just n -> n + 1
Nothing -> 0
Upvotes: 6