Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What do symbols <$> and <*> mean in Haskell?

Tags:

haskell

What do the symbols <$> and <*> mean?

Also, I find some information about <$ and $>.

like image 310
Denis Avatar asked Apr 03 '15 18:04

Denis


2 Answers

These operators are defined in Control.Applicative. The <$> operator is just an infix version of fmap:

f <$> a = fmap f a

And <*> is part of the Applicative typeclass definition:

class Functor f => Applicative f where
    pure :: a -> f a
    (<*>) :: f (a -> b) -> f a -> f b

You can search for Haskell functions and operators more easily with hoogle.

The Applicative typeclass come in between Functor and Monad:

class Functor where ...

class Functor f => Applicative f where ...

class Applicative m => Monad m where ...

(Note that this is relationship between Applicative and Monad only enforced in the recently released GHC 7.10)

Applicatives are structures that follow specific rules. It's more powerful than a functor but less powerful than a monad. Specifically a functor can only apply a single-argument function to values in a structure, returning a new structure that contains new values but not a new shape. The canonical example is fmap (+1) [1,2,3] == [2,3,4], the length of the input list is always the same as the output list. With applicatives, you can apply a multi-argument pure function across multiple structures:

> (+) <$> [1, 2, 3] <*> [10, 20]
[11, 21, 12, 22, 13, 23]

The output list's length (its "shape") depends on the lengths of the input lists. However, something to note is that the length of the output list does not depend on the values inside the list. This is the power that monads add to this hierarchy:

> print $ do a <- [1, 2, 3]; b <- replicate a 10; return (a + b)
[11, 12, 12, 13, 13, 13]

Here we are combining two structures together, one of which has a "shape" that depends on the values in the other. This is not possible with just applicatives, and it's the reason why monads are so ubiquitous in Haskell. However, since every Monad is an Applicative and every Applicative a Functor, you still have access to all these tool when working with Monads.

like image 88
bheklilr Avatar answered Nov 07 '22 16:11

bheklilr


<$> is a synonymous of fmap, <$> is the infix operator. It usually used in the context of an applicative functor.

import Control.Applicative ((<$>)

-- (<$>), fmap :: Functor f => (a -> b) -> f a -> f b

example1 :: (Int -> Int) -> Maybe Int -> Maybe Int
example1 f g = f <$> g  -- f `fmap` (Just x) = Just (f x)
                        -- f `fmap` Nothing  = Nothing

On the other hand the <*> is useful when you have a function in the context of a functor and you want to apply that to some value in a another functor context, for instance:

example2:: Maybe (Int -> Int) -> Maybe Int -> Maybe Int
example2 f g = f <*> g -- (Just f) <*> (Just x) = Just ( f x)
                       -- Nothing  <*> (Just x ) = Nothing
                       -- (Just f) <*> Nothing   = Nothing
                       -- Nothing <*>  Nothing   = Nothing

It can be pictured as an operator that applies a function and simultaneously takes into account the context in which the function is applied.

These operators lift the values and functions to the context of the Functor in which the operations are carry out.

like image 45
felipez Avatar answered Nov 07 '22 18:11

felipez