lesserKind :: ClassMap -> Kind -> Kind -> Bool
lesserKind cm k1 k2 = case k1 of
    ClassKind c1 -> (case k2 of
        ClassKind c2 -> c1 == c2 || (k1 /= universe && k2 == universe)
        _ -> False) ||
          case Map.lookup c1 cm of
          Just info -> not $ newKind cm k2 $ classKinds info
          _ -> False
    FunKind v1 a1 r1 _ -> case k2 of
        FunKind v2 a2 r2 _ -> lesserVariance v1 v2
            && lesserKind cm r1 r2 && lesserKind cm a2 a1
        _ -> False

-- | compare raw kinds
lesserKind :: ClassMap -> Kind -> Kind -> Bool
lesserKind cm k1 k2 = case k1 of
    ClassKind c1 -> (case k2 of
        ClassKind c2 -> c1 == c2 || (k1 /= universe && k2 == universe)
        _ -> False) ||
          case Map.lookup c1 cm of
          Just info -> not $ newKind cm k2 $ classKinds info
          _ -> False
    FunKind v1 a1 r1 _ -> case k2 of
        FunKind v2 a2 r2 _ -> lesserVariance v1 v2
            && lesserKind cm r1 r2 && lesserKind cm a2 a1
        _ -> False

-- | compare raw kinds
lesserKind cm k1 k2 = case k1 of
    ClassKind c1 -> (case k2 of
        ClassKind c2 -> c1 == c2 || (k1 /= universe && k2 == universe)
        _ -> False) ||
          case Map.lookup c1 cm of
          Just info -> not $ newKind cm k2 $ classKinds info
          _ -> False
    FunKind v1 a1 r1 _ -> case k2 of
        FunKind v2 a2 r2 _ -> lesserVariance v1 v2
            && lesserKind cm r1 r2 && lesserKind cm a2 a1
        _ -> False

-- | compare raw kinds