I have the following function that acts like an index operator:
let {
index :: [a]->Int->Maybe a
index [] i = error "Empty list"
index l i = if i <= ((length l) - 1) && i >= 0 then
Just(l !! i)
else
error "Index out of bounds"
}
Now, initially i wrote this without using Just (and i still don’t understand what it is after googling):
let {
index :: [a]->Int->Maybe a
index [] i = error "Empty list"
index l i = if i <= ((length l) - 1) && i >= 0 then
(l !! i)
else
error "Index out of bounds"
}
To me it the above function makes perfect sense. Because here i have a function that accepts a list of ‘generic type’ a and an Int which is the index and returns Maybe value of type a or throws runtime exception. However, i don’t understand the bit where GHCi tells me this:
<interactive>:1:120:
Couldn't match type `a' with `Maybe a'
`a' is a rigid type variable bound by
the type signature for index :: [a] -> Int -> Maybe a
at <interactive>:1:34
Expected type: [Maybe a]
Actual type: [a]
In the first argument of `(!!)', namely `l'
In the expression: (l !! i)
Now, why is GHCi getting confused with the type of l and why is it expecting a list of type Maybe a? Finally, how does Just resolve the problem?
You’ve specifically stated in your type annotation that your function
indexreturns aMaybe a.Maybe is a data type defined in Haskell thusly:
That is, it has two value constructors,
Just :: a -> Maybe aandNothing :: Maybe a. Thus, in order for you function to work correctly, it must return either aJust aor aNothing.This also means that you should be able to remove your error statements with a bit of thought and encode the actual error in the
Nothing(ie. we were out of bounds, no element here!) and only return a resultJust aif it makes sense.