Hello!
Example: I wish to define a structured container type, let's call it a "RatsNest", that is type-variable in two ways:
(a) it is parameterized by a type of some class, let's call it "RatsTail", such that a RatsNest is a structure of things that have common properties. Certain operations between RatsNest values (e.g. a merge) are valid only if they are containers for the same kind of RatsTail. Such operations would not be different operations due to variation of thye contained type.
(b) it can be implemented in various ways; e.g. a simple version is an in-memory data structure, while another may be implemented in database storage. This corresponds to the Haskell idea of overloading, or classes.
Do you consider the standard design lacking? For example, -- sort of things to put into a RatNest class (Eq n) => RatTail n where is_the_same_rat:: n -> n -> Bool class (RatTail t) => RatNest c t where in_nest:: c t -> t -> Bool put:: c t -> t -> c t rat_fold:: (t -> z -> z) -> z -> (c t) -> z merge:: (RatNest c1 t) => c t -> c1 t -> c t merge c c1 = rat_fold put_perhaps c c1 where put_perhaps rat nest = if in_nest nest rat then nest else put nest rat instance RatTail Int where is_the_same_rat = (==) -- Pretend this is an in-memory implementation instance (RatTail t) => RatNest [] t where in_nest lst el = not $ null $ filter (is_the_same_rat el) lst put = (flip (:)) rat_fold = foldr -- Pretend this is a "disk" implementation -- At least it's unmarshalled. newtype Disk t = D String deriving Show instance (Read t, Show t, RatTail t) => RatNest Disk t where in_nest disk el = rat_fold (\item z -> z || is_the_same_rat item el) False disk put (D block) item = D $ '|' : ((show item) ++ block) rat_fold f z (D []) = z rat_fold f z (D ('|':block)) = f item $ rat_fold f z (D rest) where [(item,rest)] = readsPrec 1 block nest1 = [1,12,123] :: [Int] nest2 = D "" test1 = merge nest2 nest1 -- D "|1|12|123" test1' = merge test1 nest1 -- D "|1|12|123" test2 = merge [4,5,123] test1 -- [1,12,4,5,123] Haskell extensions are required, of course, because we use multi-parameter type classes.