If you have a unary function F, you can compose it with function G, H = F ∘ G, which means H(x) = F(G(x)). Instead of running x through F directly, you run it through G first and then run the output of G through F.
If F is a binary function, then you either compose it with a unary function G on the left input: H = F ∘left G, which means H(x, y) = F(G(x), y) or you compose it with a unary function G on the right input: H = F ∘right G, which means H(x, y) = F(x, G(y)).
(binary-compose-left f g) = (λ (x y) (f (g x) y)) (binary-compose-right f g) = (λ (x y) (f x (g y)))
We could extend this to trinary functions and beyond, but it is less common to want to compose functions with more than two inputs.
binary-compose-right comes in handy when combined
with fold-left. This identity holds
(fold-left (binary-compose-right f g) acc lst) <=> (fold-left f acc (map g lst))
but the right-hand side is less efficient because it requires an extra pass through the list to map g over it before folding. The left-hand side is more efficient because it composes g with f on the fly as it folds, so it only requires one pass through the list.
No comments:
Post a Comment