Haskell is a quirky language to say the least. I've been playing around with it for about a month now. Today somebody pointed out that I was "doing it wrong" with one of my functions. I had it defined as (roughly)
pos :: (Eq a) => [a] -> a -> Int
pos  _ = 0
pos a@(x:xs) y
| (y `notElem` a) = -1
| x == y = 0
| otherwise = 1 + (pos xs y)
The obvious problem with this is that if y is not a part of the list (and yeah, it will check every time, also bad) it returns -1. -1 is a hack in a lot of procedural languages that means "Woah there nelly, something went wrong". In Haskell it doesn't have to be this way.
What Maybe is
Maybe is a type with two type constructors (Just and Nothing). Just uses a type variable whereas nothing has no parameters. Either the thing is returned or it is not, end of story.
Here is a function that returns an int if the number parameter is less than 10, nothing otherwise.
test :: Int -> Maybe Int
| x < 10 = Just x
| otherwise = Nothing
Remember that Just and Nothing are not types, but rather they are type constructors, which is why we can put them in the type signature under "Maybe".
How to use Maybe values
To "extract" a maybe value, you either have to make the function accept a maybe or extract the value beforehand.
Extracting the Maybe Value
Here is an extracting function that if it is a Maybe of a it will return the a, but otherwise unit (Won't actually work; just case in point)
extract :: Maybe a -> a
extract (Maybe a) = a
extact (Nothing) = ()
Make one of these extracting functions for whatever type you think you will be using.
To destructure a maybe within the function, just include the type constructor like was done in extract. This is what pattern matching was made for.