I try to understand how data type families can be used to hide away a constructor. The trivial example given is a pair with operations to convert from and to ordinary pairs etc.). An instance for bifunctor does not compile; the error message is
src/TypeFamilyTest.hs:66:21: The first argument ofBifunctorshould have kind* -> * -> *, butPairs a bhas kindghc-prim-0.4.0.0:GHC.Prim.ConstraintIn the instance declaration for
Bifunctor (Pairs a b)
Trying Bifunctor Pair where ... I get another error message listing the same GHC.Prim.Constraint. What are the correct arguments for the instance and how will the context be passed?
class Pairs a b where
data Vec2 a b
mkPair :: (a,b) -> Vec2 a b -- (FirstF a, SecondF a) -> a
splitPair :: Vec2 a b -> (a,b)
fstP :: Vec2 a b -> a
sndP :: Vec2 a b -> b
fstP = fst . splitPair
sndP = snd . splitPair
instance ( ) => Bifunctor (Pairs a b) where
bimap opv oph vh = mkPair (opv . fstP $ vh, oph . sndP $ vh)
classis a Java-likeinterface, and even this correspondence is loose. - chinewtype Vec2' a b = Vec2' (Vec2 a b)and you can make instances of typeclasses for this type to your hearts content. However, this type is not aBifunctor. The type ofbimapwould be(Pairs a b, Pairs a' b') => (a -> a') -> (b -> b') -> Vec2' a b -> Vec2' a' b'- user2407038