Search code examples
haskellpointfree

Pointfree (or library) function for applying two functions to single input


I keep reusing lambda expressions such as

\x -> (f x, g x)

where I apply the same input to two functions and encapsulate the result in a pair. I can write a function capturing this

combine :: (a -> b) -> (a -> c) -> a -> (b,c)
combine f g x = (f x, g x)

Now the above lambda expression is just combine f g. I have two questions.

  1. I'm interested to know if there is a standard library function that does this that I just can't find.
  2. Out of curiosity, I'd like to rewrite this function in point-free style, but I'm having a lot of trouble with it.

Solution

    1. Control.Arrow has the function (&&&) for this. It has a "more general" type, which unfortunately means that Hoogle doesn't find it (maybe this should be considered a bug in Hoogle?).

    2. You can usually figure this sort of thing automatically with pointfree, which lambdabot in #haskell has as a plugin.

    For example:

    <shachaf> @pl combine f g x = (f x, g x)
    <lambdabot> combine = liftM2 (,)
    

    Where liftM2 with the (r ->) instance of Monad has type (a -> b -> c) -> (r -> a) -> (r -> b) -> r -> c. Of course, there are many other ways of writing this point-free, depending on what primitives you allow.