Могу ли я убедить компилятор, что ограничение всегда выполняется синонимами типа в закрытом типе? Семейство индексируется конечным набором продвинутых значений.
Что-то вдоль линий
data NoShow = NoShow
data LiftedType = V1 | V2 | V3
type family (Show (Synonym (a :: LiftedType)) => Synonym (a :: LiftedType)) where
Synonym V1 = Int
Synonym V2 = NoShow -- no Show instance => compilation error
Synonym V3 = ()
Я могу принудительно применять ограничение для типов открытых типов:
class (Show (Synonym a)) => SynonymClass (a :: LiftedType) where
type Synonym a
type Synonym a = ()
instance SynonymClass Int where
type Synonym V1 = Int
-- the compiler complains here
instance SynonymClass V2 where
type Synonym V2 = NoShow
instance SynonymClass V3
но компилятор тогда должен был бы рассуждать о том, что существует экземпляр SynonymClass a
для каждого из V1
, V2
и V3
? Но в любом случае я бы предпочел не использовать семейство открытого типа.
Моей мотивацией для этого является то, что я хочу убедить компилятор, что все экземпляры семейства закрытого типа в моем коде имеют экземпляры Show/Read. Упрощенный пример:
parseLTandSynonym :: LiftedType -> String -> String
parseLTandSynonym lt x =
case (toSing lt) of
SomeSing (slt :: SLiftedType lt') -> parseSynonym slt x
parseSynonym :: forall lt. SLiftedType lt -> String -> String
parseSynonym slt flv =
case (readEither flv :: Either String (Synonym lt)) of
Left err -> "Can't parse synonym: " ++ err
Right x -> "Synonym value: " ++ show x
[Кто-то упомянул в комментариях, что это невозможно - это потому, что это технически невозможно (и если да, почему) или просто ограничение реализации GHC?]