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 ofBifunctor
should have kind* -> * -> *
, butPairs a b
has kindghc-prim-0.4.0.0:GHC.Prim.Constraint
In 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)
class
is 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 ofbimap
would be(Pairs a b, Pairs a' b') => (a -> a') -> (b -> b') -> Vec2' a b -> Vec2' a' b'
– user2407038