Let me guess we're about to filter a list of integers, `xs`.

``````xs = [1..100]
``````

It's not a big deal in Haskell to filter even numbers out.

``````filter odd xs
``````

It's the same when getting only numbers larger than 50.

``````filter (> 50) xs
``````

So far, so good. But what if we want to get numbers which are odd and larger than 50 at the same time? Maybe we should use `&&`?

``````filter (odd && (> 50)) xs
``````

The code above doesn't work because what we want to `&&` is the result of the functions, not the functions themselves. The types are mismatched:

``````odd :: Integral a => a -> Bool
(> 50) :: (Ord a, Num a) => a -> Bool
&& :: Bool -> Bool -> Bool
``````

Both of the parameters of `&&` should be `Bool`, not `a -> Bool`.

Then, how about the code below? What we want to do is basically something like function composition, so may it work?

``````filter (odd . (> 50)) xs
``````

The answer is, as you may have expected, no. The types are also mismatched too:

``````odd :: Integral a => a -> Bool
(> 50) :: (Ord a, Num a) => a -> Bool
(.) :: (b -> c) -> (a -> b) -> a -> c
``````

What we want is actually a function having a type `(a -> Bool) -> (a -> bool) -> a -> Bool`. Then why not create one?

``````and :: (a -> Bool) -> (a -> Bool) -> a -> Bool
and f g x = (f x) && (g x)

filter (odd `and` (> 50)) xs
``````

Easy. We can make it in more general form.

``````lift :: (x -> y -> z) -> (a -> x) -> (a -> y) -> a -> z
lift f g h x = f (g x) (h x)
and = lift (&&)

filter (odd `and` (> 50)) xs
``````

Cool! `lift` actually lifts a function with type `x -> y -> z` to be applied into other functions! But wait, `lift`'s looking so useful. Why not have it in Haskell by default?

``````import Control.Monad (liftM2)

and = liftM2 (&&)

filter (odd `and` (> 50)) xs
``````

Yes, we already have. Haskell is awesome. So, the type of `liftM2` is `(x -> y -> z) -> (a -> x) -> (a -> y) -> a -> z`, right?

``````liftM2 :: Monad m => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
``````

What? `Monad`? No, no, no, we've talked about compositing functions, not about monad. Is this article another monad tutorial? No. I promise it won't be. Monad itself is not what I want to talk about in this article. I still want to talk about function composition. Then, why the heaven is the term `Monad` coming out in the type of `liftM2`? Well, in Haskell, function is monad. No, more specifically, function can be a kind of monad, something called reader monad.

``````instance Monad ((->) x)
``````

`((->) x)` is just the prefix form of `x ->`. Now, let's replace `m` in the type of `liftM2` with this, because `x ->` is an instance of `Monad m`.

``````liftM2 :: Monad m => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2' :: (a1 -> a2 -> r) -> (x -> a1) -> (x -> a2) -> (x -> r)
``````

By alpha equivalence, it's exactly the same type as `lift` we made above.

There are similar functions such as `liftM`, `liftM3`, `liftM4`, `liftM5`, and `liftM6`. Sorry, I lied. There's no `liftM6`, 5 is enough! Anyway, they are all about lifting a function with n parameters, making it able to be applied to monadic values. In easy words, it makes functions to work well with some complex values, as we made `&&` work with complex values, in our case, return values of other functions (`odd`, `(> 50)`).