Van egy ilyen típusú osztályom:
class (Coercible a b) => Foo a b | a -> b
Szeretném deklarálni a Generic
következő példányát:
data Thing a
where
Thing :: Foo a b => b -> Thing a
-- If the @b@ uniquely determined by @a@ is @Generic@, so is @Thing a@ ...
instance (Foo a b, Generic b) => Generic (Thing a)
where
type Rep (Thing a) = Rep b
Sajnos ez nem fordítható le, a hibaüzenet a következő:
[typecheck] [E] • Type variable ‘r’ is mentioned in the RHS,
but not bound on the LHS of the family instance
• In the type instance declaration for ‘Rep’
In the instance declaration for ‘Generic (UnvalidatedData v)’
Tudom, hogy amit akarok, az szemantikai szinten lehetséges, mert ha funkcionális függőség helyett típuscsaládot használok a következőképpen:
class (Coercible a (B a)) => Foo' a
where
type B a :: Type
Kijelenthetem:
data Thing a
where
Thing :: Foo' a => B a -> Thing a
-- If the @B a@ uniquely determined by @a@ is @Generic@, so is @Thing a@ ...
instance (Foo' a, Generic (B a)) => Generic (Thing a)
where
type Rep (Thing a) = Rep (B a)
Sajnos a társított típuscsaládok egyáltalán nem jelennek meg a típusosztályok típusaiban, így nem lehetséges magasabb rendű érvelés a társított típuscsaládok felett az osztályok áthaladásakor. Emiatt a típuscsalád helyett inkább funkcionális függőséget használnék.
Mi (ha van) a legközelebbi működő közelítése Foo
, Thing
és Thing
Generic
példányának, amely többparaméteres típusosztályt használ?