Using a lifted version of (,) for the cartesian product of constraint seems to work until you want to use the fact that it's cartesian, which GHC seems unaware of.
GHC seems to treat '(,) as just an monoïdal product, leading to the error
• Could not deduce: ax ~ '(a, x) arising from a use of ‘Dict’
from the context: (a ~ Fst ax, x ~ Snd ax)
Although Fst and Snd are not just any projections, they are the cartesian one.
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE UndecidableSuperClasses #-}
module SO.SO_CartesianProduct where
data Dict c = c => Dict
type family Fst (ij :: (i, j)) :: i
type instance Fst '(i, j) = i
type family Snd (ij :: (i, j)) :: j
type instance Snd '(i, j) = j
class (a ~ Fst ax, x ~ Snd ax) => IsProd ax a x where d :: Dict (ax ~ '(a, x))
instance (a ~ Fst ax, x ~ Snd ax) => IsProd ax a x where
d = Dict -- • Could not deduce: ax ~ '(a, x) arising from a use of ‘Dict’
-- from the context: (a ~ Fst ax, x ~ Snd ax)
An attempt to instruct GHC of that fact fails
-- Fails
instance (a ~ Fst ax, x ~ Snd ax) => (ax ~ '(a, x))
-- • Class ‘~’ does not support user-specified instances
-- • In the instance declaration for ‘(ax ~ '(a, x))’typ
Is there anyway to instruct GHC that it's actually cartesian, or to get a product recognized as cartesian by GHC in some way ?