So I often find myself designing 'pipeline' like flows of data, and oftentimes it ends up that the pipeline itself is dynamic.
Is there an easy way to do something like this?
pipe :: [a -> a] -> a -> a
Or is there a different pattern I should be reaching for with something like this? It's similar to the State monad, but I don't want to have to edit the functions to be (a -> (), a)
or whatever :/
I realized that this is a monoid, so I wrote this, which seems like an elegant solution, does this exist in a library somewhere? It seems like most Arrow and Function Monoids do different things.
newtype Comp a = Comp {
runComp :: a -> a
}
instance Monoid (Comp a) where
(Comp a) `mappend` (Comp b) = Comp (b . a)
mempty = Comp id
pipe :: [a -> a] -> a -> a
pipe = runComp . foldMap Comp
Anyone have patterns that they use for this sort of thing? Thanks!
You're looking for one of
foldr (.) id -- right-to-left
or
foldl (flip (.)) id -- left-to-right
depending on which order you want the functions composed:
ghci> foldr (.) id [(+1),(*10)] 0
1
ghci> foldl (flip (.)) id [(+1),(*10)] 0
10