data Pred a where Nonempty :: Pred [a] Id :: Pred a LengthConstrained :: (Int -> Bool) -> Pred [a] assoc :: forall a. Pred a -> a -> Bool assoc Nonempty = null assoc (LengthConstrained f) = \l -> f (length l) assoc Id = const True class WithPreds a (preds :: [Pred a]) where predfuncs :: [a -> Bool] instance WithPreds [a] [Nonempty] where predfuncs = [null] this isn't quite the right way to implement this, the instance declaration here reports that "Nonempty" is not a kind (rightfully so)