My last post had me thinking of some of the ways the function `uncurry`

is useful in Haskell. Let’s first look at the type:

`uncurry :: (a -> b -> c) -> (a, b) -> c`

Usually the results are obvious, transforming a given function by simply taking a couple of its arguments and replacing them with a single tuple argument. But sometimes we can get something a bit more interesting:

`uncurry (flip (,)) :: (a, b) -> (b, a)`

— swap tuple elements around.`uncurry (flip (,)) ("hello", "world") ==> ("world", "hello")`

`uncurry ($) :: (a -> b, a) -> b`

— function application within a tuple; second element applied to the first.`uncurry ($) ((+3), 4) ==> 7`

`uncurry const :: (a, b) -> a`

— oops! we’ve un-optimized ourselves back to the equivalent of`fst`

.`uncurry (flip const) :: (a, b) -> b`

— and we can duplicate`snd`

by adding a flip.`map . uncurry :: (a -> b -> c) -> [(a, b)] -> [c]`

— apply function over a list, getting arguments from within tuples in that list.`(map . uncurry) (+) [(1,1), (2,3), (5,10)] ==> [2,5,15]`

So basically, `uncurry`

is a heavy-duty higher-order tool for working with tuples.