main :: IO () main = pure () class ExplExists m c where explExists :: Int -> m Bool class ExplGet m c where explGet :: Int -> m c data A = A Int data B = B Word data Foo = FooA A | FooB B instance ExplExists IO Foo where explExists _ety = ... instance ExplGet IO Foo where explGet _ety = ... instance ExplExists IO A where explExists ety = do foo :: Foo <- explGet ety pure $ case foo of FooA _ -> True _ -> False instance ExplExists IO B where explExists ety = do foo :: Foo <- explGet ety pure $ case foo of FooB _ -> True _ -> False instance ExplGet IO A where explGet ety = do foo :: Foo <- explGet ety pure $ case foo of FooA a -> a _ -> error "accessing non-existent component" instance ExplGet IO B where explGet ety = do foo :: Foo <- explGet ety pure $ case foo of FooB b -> b _ -> error "accessing non-existent component"