What I roughly want is this:
data A = ...
data B = ...
data C = ...
class HasA t where
getA :: t -> A
class HasB t where
getB :: t -> B
class HasC t where
getC :: t -> C
So I can do something like this (pseudocode follows):
a :: A
b :: B
x = mkRecord { elemA a, elemB b }
y = mkRecord { elemB b, elemA a }
-- type of `x` == type of `y`
Naturally, only the appropriate get
functions work, in the above case getA
and getB
.
I'd also like the following functions
slice :: Subset a b => a -> b
slice x = -- just remove the bits of x that aren't in type b.
add :: e -> a -> a ++ e
add e x = -- add an element to the "record" (compile error if it's already there)
I feel like this is not a new problem so perhaps a resolution for this already exists. Note that I don't require the solution to be extensible, the amount of types I need to deal with is finite and known, but of course and extensible one wouldn't hurt.
I've found a couple of packages that seem to be in the field of what I'm looking for, namely HList and extensible (perhaps extensible is better because I want my records unordered). I got a bit lost in the Hackage docs so I'd like just some sample code (or a link to some sample code) that roughly achieves what I'm looking for.