Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What do people use the identity function for? [duplicate]

For example, Haskell has the id function, Julia has the identity function, and many questions on SO deal with the identity function. (I suppose in Python you can do lambda x:x)

I've been busting my brain trying to think of a use case for this function; and I've failed.

What is the purpose of the identity function, and what are its common use-cases?

like image 996
PythonNut Avatar asked Sep 23 '14 04:09

PythonNut


3 Answers

Remember that in Haskell functions are first class values, and can be used as data the same way as other values, and passed as arguments to other functions. Often you build the functions you really want to use by applying other functions to each other. Occasionally you will find that the function you want to use in a spot happens to be nothing more complicated than id.

For example, here is a function that negates every second element of a list:

negateEverySecond = zipWith id (cycle [id, negate])
like image 152
Ørjan Johansen Avatar answered Oct 07 '22 22:10

Ørjan Johansen


In Julia (in the standard library): A quick grep shows that currently the most prominent use of the identity function is as the default value of the by argument for various sorting related functions, such as sort!, sort, issorted, etc.

The by argument allows to specify a function to extract a sorting key from each object, so that two objects a and b are compared according to by(a) < by(b) rather than a < b. The identity function is natural as the default, since identity(a) < identity(b) is just the same as a < b.

There is also some internal sorting code that is special-cased for when by is identity, which should allow more efficient code for the common case.

like image 44
Toivo Henningsson Avatar answered Oct 07 '22 20:10

Toivo Henningsson


id can be a good place to start when building up functions. For instance,

foldl f init xs = foldr (\x r -> \acc -> r (f acc x)) id xs $ init

chi mentions

type K a = (a -> Int) -> Int
-- factorial, CPS
factCPS :: Int -> K Int
factCPS 0 k = k 1
factCPS n k = factCPS (n-1) (k . (*n))

-- factorial, plain
fact :: Int -> Int
fact n = factCPS n id

This approach is actually closely related to the example I give above; the id in the definition of foldl is really just the continuation to use.

fact q
  = foldl (*) 1 [1..q]
  = foldr (\x r -> \acc -> r (acc * x)) id (build
      (\c n -> if q<1
               then n
               else let go k | k <= q = k `c` go (k+1)
                             | otherwise = n
                    in go 1)) 1
  -- foldr/build
  = (if q < 1
     then id
     else let go k | k <= q = \acc -> go (k+1) (acc * k)
                   | otherwise = id = \acc -> acc
          in go 1) 1
  = (if q < 1
     then id
     else let go k acc | k <= q = go (k+1) (acc * k)
                       | otherwise = acc
          in go 1) 1
  = if q < 1
    then 1
    else let go k acc | k <= q = go (k+1) (acc*k)
                      | otherwise = acc
         in go 1 1
like image 36
dfeuer Avatar answered Oct 07 '22 21:10

dfeuer