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 `index`

returns a `Maybe a`

.

Maybe is a data type defined in Haskell thusly:

```
data Maybe a = Just a | Nothing
```

That is, it has two value constructors, `Just :: a -> Maybe a`

and `Nothing :: Maybe a`

. Thus, in order for you function to work correctly, it must return either a `Just a`

or a `Nothing`

.

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 result `Just a`

if it makes sense.