According to this article, in object-oriented programming / design dependency injection involves
- a dependent consumer,
- a declaration of a component's dependencies, defined as interface contracts,
- an injector that creates instances of classes that implement a given dependency interface on request.
Let us now consider a higher-order function in a functional programming language, e.g. the Haskell function
filter :: (a -> Bool) -> [a] -> [a]
Data.List. This function transforms a list into another list and, in order to perform its job, it uses (consumes) an external predicate function that must be provided by its caller, e.g. the expression
filter (\x -> (mod x 2) == 0) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
selects all even numbers from the input list.
But isn't this construction very similar to the pattern illustrated above, where
filterfunction is the dependent consumer,
- the signature
(a -> Bool)of the function argument is the interface contract,
- the expression that uses the higher-order is the injector that, in this particular case, injects the implementation
(\x -> (mod x 2) == 0)of the contract.
More in general, can one relate higher-order functions and their usage pattern in functional programming to the dependency injection pattern in object-oriented languages?
Or in the inverse direction, can dependency injection be compared to using some kind of higher-order function?