
I admit I haven't read this whole thread in detail, but when I want something with an implementation that can vary dynamically I just pass a different function. Your original python example is equivalent to just passing strings in haskell, so lets add an argument: type Process = Int -> String heterogeneousProcessor :: [Process] -> [String] heterogeneousProcessor ps = [p 42 | p <- ps] -- or map ($42) ps variant1 n = "variant1 stuff " ++ show n -- etc. Now the user of your library can pass their own Process. I have a number of records in my program like "State { lookup_x :: Name -> Maybe X, lookup_y :: Name -> Maybe Y, do_something_important :: X -> Result }". They reduce dependencies by not exposing the (complicated) lookup details and types, and aid testing because I can just pass a state with a dummy 'do_something_important' (in my case, it's "update GUI", which is important to stub out for a test). This may be simpler than what you had in mind, but to narrow it down, could you provide a more specific example where this is inadequate?