22

What are these operators doing?

(.) :: (b -> c) -> (a -> b) -> a -> c
(<$>) :: Functor f => (a -> b) -> f a -> f b
(<*>) :: Applicative f => f (a -> b) -> f a -> f b

I don't have any idea when I see the signatures. Perhaps some example with a simple and easy to understand explanation will help me.

peterh
  • 11,875
  • 18
  • 85
  • 108
develhevel
  • 3,161
  • 4
  • 21
  • 27

5 Answers5

31

I am also learning Haskell, and my recommendation is to have a look into Learn You a Haskell for Great Good!, and more precisely:

In essence:

  • (.) is function composition: if you have g :: a -> b and f :: b -> c then f . g is essentially f(g(x)): first use g on an a to get a b and then use f on that b to get a c

  • <$> takes a function taking an a and returning a b, and a functor that contains an a, and it returns a functor that contains a b. So <$> is the same as fmap :: (a -> b) -> f a -> f b

  • <*> takes a functor that contains a function taking an a and returning a b, and a functor that contains an a, and it returns a functor that contains a b. So <*> kind of extract the function from a functor and applies it to an arguments also inside a functor, and finally returns the result into a functor

Note the explanations that you find in the book chapters are better than my attempt above

MarcoS
  • 13,386
  • 7
  • 42
  • 63
  • 3
    [RWH](http://book.realworldhaskell.org/read/code-case-study-parsing-a-binary-data-format.html#binary.functor) and the [Typeclassopedia](http://www.haskell.org/haskellwiki/Typeclassopedia) are also good sources for this question after reading LYAH. – Dan Burton Jun 08 '11 at 18:01
23

Maybe you learn via examples (like I do), so here are some simple ones you can mess around with in GHCI.

(.) - Function Composition 
-- (.) :: (b -> c) -> (a -> b) -> a -> c
> f = (+1)
> g = (*2)
> a = f . g
> a 0
1 -- f( g( 0 ) ) or (0 * 2) + 1
> b = g . f
> b 0
2 -- g( f( 0 ) ) or (0 + 1) * 2


<$> - Functor
-- (<$>) :: Functor f => (a -> b) -> f a -> f b
> a = (*2)
> b = Just 4
> a <$> b
Just 8


<*> - Applicative
-- (<*>) :: Applicative f => f (a -> b) -> f a -> f b
> a = Just (*2)
> b = Just 4
> a <*> b
Just 8

I hope that helps.

tylerweir
  • 1,265
  • 11
  • 16
3

The (.) operator composes functions. For example, \x -> f (g x) is the same as f . g. You can do this for arbitrary functions, e.g. \x -> f (g (h x)) equals f . g . h.

The <$> and <*> operators are not defined in terms of functionality. Their functionality depends on the actual type f that they are applied on. The <$> operator is an alternative for the fmap function in the Functor library. For example, for the Maybe type it takes the left operand and only applies it if the right operand is a Just value. So in order to find out what these operators do, just have a look at the implementations for the specific types.

Chris Eidhof
  • 1,514
  • 1
  • 12
  • 15
1

I'm a a newbie to Haskell and sometimes Haskell type declarations confuse me, too.

It's easy to get lost at first because the tutorial says that the Capitalization naming convention is usually for type declaration and the camelCase naming convention is usually for variable.

Actually, this belongs to a higher technique in Haskell, may be polymorphism. Just think of f, a and b as some kind type variables - variables that handle type. And class in Haskell is not for Object like OOP but for type. So Functor f means that type f belongs to class Functor and so on.

If you replace these letter a, b, c with some type - called instance - for example String Int Char. It will make sense:

(.) :: (Int -> Char) -> (String -> Int) -> String -> Char
(<$>) :: Functor Maybe => (String -> Int) -> Maybe String -> Maybe Int -- type `Maybe` belongs to class `Functor`
...
Clite Tailor
  • 438
  • 5
  • 14
0

While the common uses of <$> and <*> is obscured by the fact that they are in a typeclass, you can usually read the haddock documentation for this information. Use Hoogle if you have a hard time finding to which module a function belongs.

Thomas M. DuBuisson
  • 64,245
  • 7
  • 109
  • 166