What's the point of 'const' in the Haskell Prelude?

Looking through the Haskell Prelude, I see a function const:

const x _ = x

I can't seem to find anything relevant regarding this function.

What's the point? Can anyone give an example of where this function might be used?


Solution 1:

It's useful for passing to higher-order functions when you don't need all their flexibility. For example, the monadic sequence operator >> can be defined in terms of the monadic bind operator as

x >> y = x >>= const y

It's somewhat neater than using a lambda

x >> y = x >>= \_ -> y

and you can even use it point-free

(>>) = (. const) . (>>=)

although I don't particularly recommend that in this case.

Solution 2:

To add to hammar's excellent direct answer: humble functions like const and id are really useful as a higher order function for the same reason that they are fundamental in the SKI combinator calculus.

Not that I think haskell's prelude functions were modeled consciously after that formal system or anything. It's just that creating rich abstractions in haskell is very easy, so you often see these types of theoretical things emerge as practically useful.

Shameless plug, but I blogged about how the Applicative instance for (->) are actually the S and K combinators here, if that's the kind of thing you're into.

Solution 3:

I can't seem to find anything relevant regarding this function.

Many of the other answers discuss relatively esoteric (at least to the newcomer) applications of const. Here is a simple one: you can use const to get rid of a lambda that takes two arguments, throws away the first one but does something interesting with the second one.

For instance, the following (inefficient but instructive) implementation of length,

length' = foldr (\_ acc -> 1 + acc) 0

can be rewritten as

length' = foldr (const (1+)) 0

which is perhaps more elegant.

The expression const (1+) is indeed semantically equivalent to \_ acc -> 1 + acc, because it takes one argument, throws it away, and returns the section (1+).

Solution 4:

A simple example for using const is Data.Functor.(<$). With this function you can say: I have here a functor with something boring in it, but instead I want to have that other interesting thing in it, without changing the shape of the functor. E.g.

import Data.Functor

42 <$ Just "boring"
--> Just 42

42 <$ Nothing
--> Nothing

"cool" <$ ["nonsense","stupid","uninteresting"]
--> ["cool","cool","cool"]

The definition is:

(<$) :: a -> f b -> f a
(<$) =  fmap . const

or written not as pointless:

cool <$ uncool =  fmap (const cool) uncool

You see how const is used here to "forget" about the input.