I've read somewhere that [id
] is used to "leave something alone" but can't seem to get my head around it.
id
is used to "leave something alone" because that is all it does -- that is, nothing:
id :: x -> x
id x = x
That being so, id
often shows up as a do-nothing placeholder passed to higher-order functions. fmap id foo
doesn't actually change the values found within foo
(in fact, fmap id = id
, which is the first functor law), id . f
and f . id
are both equivalent to f
, and so forth. A more interesting example is the classic trick of defining foldl
using foldr
, in which id
is used as a base case for building a function with foldr
.
For example, why is the type of liftA2 id
f (b -> c) -> f b -> f c
?
The type of liftA2
is:
liftA2 :: (a -> b -> c) -> f a -> f b -> f c
In the case of liftA2 id
, we have...
(a -> (b -> c)) ~ (x -> x)
... and so...
a ~ x
(b -> c) ~ x
... therefore...
liftA2 id :: f (b -> c) -> f b -> f c
(As you probably know, liftA2 id = (<*>)
. What is going on is perhaps more obvious if you write it as liftA2 ($)
, ($) :: (a -> b) -> (a -> b)
being merely a specialised id
.)
Also, why can't I pass id
to g
for
g :: (Int -> Int -> Int) -> Int -> Int -> Int
Because then you'd have to unify...
(Int -> (Int -> Int)) ~ (x -> x)
... which is impossible, as x
cannot be both Int
and Int -> Int
.