Too Long; Didn't Read
The repository pattern is a common design pattern used as a data access abstraction. It allows you to perform your typical CRUD operations without the client having to interact directly with the data provider. Using higher-order functions, we can define a single method that gets IEnumerable<Product> that takes a filter function as an input. That way, the client is free to define their own filters, and the ProductRepository doesn't need to keep being updated with new implementations. For example, the Map function takes a list of a particular data type and a function that returns a new list with the function applied to each of the elements.