This should work:
data Conjunction f = Conj ff instance Formula f => Formula (Conjunction f) where evaluate (Conj Ο Ο) v = evaluate Ο v && evaluate Ο v
However, I'm not sure if type classes are the right tool for what you are trying to achieve.
Perhaps you could let the vortex use explicit type-level functions and repeat over them:
-- functor for plain formulae data FormulaF f = Prop {propName :: String} | Neg f | Conj ff | Disj ff | Impl ff | BiImpl ff -- plain formula newtype Formula = F {unF :: FormulaF Formula} -- functor adding a modality data ModalF f = Plain f | MyModality f -- modal formula newtype Modal = M {unM :: ModalF Modal}
Yes, this is not very convenient, since constructors such as F,M,Plain sometimes interfere. But, unlike type classes, you can use pattern matching here.
As another option, use GADT:
data Plain data Mod data Formula t where Prop {propName :: String} :: Formula t Neg :: Formula t -> Formula t Conj :: Formula t -> Formula t -> Formula t Disj :: Formula t -> Formula t -> Formula t Impl :: Formula t -> Formula t -> Formula t BiImpl :: Formula t -> Formula t -> Formula t MyModality :: Formula Mod -> Formula Mod type PlainFormula = Formula Plain type ModalFormula = Formula Mod
source share