Some pseudocode:
data A = A
data B = B
data C = C
data D = D
data E = E
data F = F
data G = G
data A1 = A1 A B C
data A2 = A2 A
data A3 = A3 B C D
data A4 = A4 D E F
data A5 = A5 A1 A4 G
data Foo k = Foo
{
a1s :: Map.Map k A1,
a2s :: Map.Map k A2,
a3s :: Map.Map k A3,
a4s :: Map.Map k A4,
a5s :: Map.Map k A5,
--and my attempted solution would use
-- e.g. [(A1, [(A, Unit), (B, Unit), (C, Unit)]), (A5, [(A1, Composite), (A4, Composite), (G, Unit) ]) ]
componentMap :: Map.Map Type (Set Type),
-- e.g. [(A, [A1, A2]), (A1, [A5, A1]) ]
compositeMap :: Map.Map Type (Set Type)
}
I'd like to construct some kind of data structure that looks like this. From here, I'd like to:
lookup :: Foo k -> k -> Either FailureReason vindividual values; if we assume that we have populated maps, I'd likelookup foo a1 :: A1, but also transitive instances such aslookup foo a1 :: Borlookup foo a5 :: A1(since this is shorthand forgetA1fromA5 $ lookup foo a5) andlookup foo a5 :: B. I'm consideringFailureReason = WrongType | NotPresentbut this is probably excessive.- traversals over types such as an (indexed) traversal over
(k, D)which should hit everything inA3, A4, A5
This could be implemented as a recursive search over componentMap and compositeMap..so long as they were populated by hand.
Since the above seem very much recursive, I feel this has a GHC.Generics solution. Possibly a lens/optics + generic-lens/generic-optics one?
Or is my solution one that doesn't need generics and its ilk, and is instead just writing some traversals and lenses to index into my structure?
The question then becomes: is this functionality already existing in some library? If not, is Generics the tool I'm looking for to implement it?