What is Just in Haskell and why this function will not work without it?

I have the following function that acts as an index operator:

let { index :: [a]->Int->Maybe a index [] i = error "Empty list" index li = if i <= ((length l) - 1) && i >= 0 then Just(l !! i) else error "Index out of bounds" } 

Now, I originally 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 li = if i <= ((length l) - 1) && i >= 0 then (l !! i) else error "Index out of bounds" } 

For me, this function makes sense. Because here I have a function that takes a list of "generic type" a and Int , which is an index, and returns a Maybe value of type a or throws an exception at runtime. 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 confused with type l and why is it expecting a list of type Maybe a ? Finally, how does Just solve the problem?

+4
source share
3 answers

You indicated in your type annotation that your index function returns Maybe a .

Perhaps this is a data type defined in Haskell:

 data Maybe a = Just a | Nothing 

That is, it has two value constructors, Just :: a -> Maybe a and Nothing :: Maybe a . Thus, for you to work correctly, it must return either Just a or Nothing .

It also means that you should be able to quickly output your error statements and encode the actual error in Nothing (that is, we were out of bounds, there is no element here!) And return Just a result if that makes sense.

+6
source

From the Data.Maybe docs :

Maybe type encapsulates an optional value. A value of type Maybe a either contains a value of type a (represented as Just a) or empty (represented as Nothing).

If you are looking for the Maybe Int type, then your function will return either Nothing or Just Int .

This is a simple kind of error monad, where all errors are represented by Nothing.

Essentially, if Nothing returns, something happened that made the function unable to find the result. The Just qualifier allows you to work with these types of Maybe .

+1
source

You told GHC the return type of index as Maybe a . This means that (l !! i) (the value returned by index ) must be of type Maybe a .

Since (l !! i) selects one element from the list l , this means that l must be of type [Maybe a] so that one of its elements is Maybe a .

But l is the first index argument that you also told GHC to type [a] .

This is exactly your mistake. The GHC tries to compile the index in [Maybe a] to get Maybe a , but instead finds that the indexed thing is [a] .

The reason Just eliminates this is because Just is of type a -> Maybe a . So when you say Just (l !! i) , the GHC now sees that you index [a] to get a , and then applying Just to what Maybe a results in, as expected.

+1
source

All Articles