Is predicate a function specific to each product, used to compose product?
Or is it used when querying products to filter them?
I'd define data structures as records, sometimes with a couple variable types. Then if variable types are used, define classes to query, modify data.
Why not define product as
data Prod a c = Prod a [c]
where a is product info and c is child item data.
Then define predicate class.
Then define a's and c's separately for each use case. Maybe add types for each specific product.
Then add instances.
This way future changes will be easy. It is easier to work on specifics when generics are simple. Specific products may be as complex as necessary.
If you define product as a complex type with a few type variables, changes will be more difficult.