It takes a bit of practice to get used to using Functors, Applicatives and Monads so here are some common patterns I have found that are more succinct when refactored. Hopefully it will help speeding up the journey to becoming a Functor ninja.

## Nested Maybes

If you have a series of nested case statements on Maybes :

```
nestedMaybePre :: Maybe Int -> Maybe Int
nestedMaybePre maybe =
case maybe of
Nothing -> Nothing
Just value -> case evenThing value of
Nothing -> Nothing
Just num -> Just num
```

Since Maybe is a monad, you can instead chain them using bind (>>=) :

```
nestedMaybePost :: Maybe Int -> Maybe Int
nestedMaybePost maybe =
maybe >>= evenThing
```

Or with `do`

notation :

```
nestedMaybePostDo :: Maybe Int -> Maybe Int
nestedMaybePostDo maybe = do
value <- maybe
evenThing value
```

## Functions on the Just

You want to call a function on the value that maybe held in a `Maybe`

:

```
somethingOnTheJust :: Maybe Int -> Maybe String
somethingOnTheJust maybe =
case maybe of
Nothing -> Nothing
Just value -> Just $ show value
```

`Maybe`

is a `Functor`

, so you can just use fmap (<$>) :

```
somethingOnTheJustPost :: Maybe Int -> Maybe String
somethingOnTheJustPost maybe = show <$> maybe
```

## Doing something with multiple Justs

You have a function that takes multiple parameters. You have multiple `Maybes`

to pass in, but if any of them are `Nothing`

the whole function should return `Nothing`

.

```
onlyMultiplyEvens :: Int -> Int -> Maybe Int
onlyMultiplyEvens num1 num2 =
case evenThing num1, evenThing num2 of
Just num1', Just num2' -> Just $ Int.rem num1' num2'
_, _ -> Nothing
```

This is where you can use the Applicative instance of Maybe.

```
onlyMultiplyEvensPost :: Int -> Int -> Maybe Int
onlyMultiplyEvensPost num1 num2 =
Int.rem <$> evenThing num1 <*> evenThing num2
```

## Bored of intermediate variables

You have a function like the following :

```
printDateAndTimePre :: Effect Unit
printDateAndTimePre = do
log "The date is "
date <- nowDate
log $ formatDate date
log "The time is"
time <- nowTime
log $ formatTime time
```

Since `nowDate`

and `nowTime`

return their values wrapped in the `Effect`

monad, you cant directly call `log $ formatDate nowDate`

as `formatDate`

needs the value pulled out of the Monad. The obvious answer is to use an intermediate variable as per the previous solution. This can get a tad arduous, so sometimes it is neater to use bind to pass the variable directly :

```
printDateAndTimePost :: Effect Unit
printDateAndTimePost = do
log "The date is "
log <<< formatDate =<< nowDate
log "The time is"
nowTime >>= formatTime >>> log
```

Note both forms of bind (>>=, =<< are possible. Use the one that makes the most sense.

Also note that because we are essentially passing the parameter to a curried version of `log formatDate`

we need to compose these two functions using function composition (<<<, >>>) rather than with $.