Clojure has a macro, ->
, which takes a piece of data and a bunch of functions, applies the data to the first function, and then applies the result of that to the next one, the result of that to the third one, and so on, finally giving you back the result of the last application.
I quite like this because instead of having to write functions backwards from the order in which they are applied, like so: (pseudo-code follows)
floor (square.root (x))
you can write them in the order that the data flows through them:
-> x (square.root, floor)
My question is, is there a standard name for this function in functional languages, in the way that map, reduce, and filter have standard names? The Clojure docs describe it as 'threading the data through the functions', but I couldn't find anything on googling the word thread
. I wrote a simple version of it in Haskell:
thread :: a -> [(a -> a)] -> a
thread x [] = x
thread x (f:fs) = thread (f x) fs
and searched for a -> [(a -> a)] -> a
on Hoogle, but that didn't come up with anything either.
While researching for this question I also gleaned that you can do a very similar thing using the function composition operators from Control.Arrow
in Haskell, like so:
($2) (sin >>> cos >>> tan)
whereas using the dedicated higher-order thread
function you would write:
thread 2 [sin, cos, tan]
Is it perhaps the case that the first formulation suffices for practical usage?
Endo a
in Data.Monoid. By analogy toSum
/sum
,All
/all
, etc, you might think there would be aendo :: [a -> a] -> a -> a
that does what you want, but there is not. – Teeendo
" could easily be written up, though:thread = flip $ appEndo . mconcat . map Endo . reverse
. Then:thread 2 [(+1), (*3)]
-> 9. (This has the argument order as in the question rather than as in the previous comment.) – TiffanyEndo
is a monoid then presumablymconcat
will fold the list into a single function, which can then be applied. – Piffle