Derleyiciyi, bir kısıtlamanın her zaman kapalı tip bir ailede eşanlamlı karakterlerden memnun olduğunu ikna edebilir miyim? Aile, sınırlı sayıda teşvik edilmiş değer dizisi ile endekslenmiştir. Açık tip ailelere bir kısıtlamayı zorlayabilirKısıtlı kapalı tip aile
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 =()
çizgisinde
şey:
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
ama derleyici sonra olurdu var olduğu gerçeği hakkında ikna etmeye muktedir V1
, V2
ve V3
'un her biri için SynonymClass a
numaralı bir örnek? Ama her durumda açık tip bir aile kullanmamayı tercih ederim.
Bunu gerektirme konusundaki motivasyonum, derleyiciyi, kodumdaki kapalı tip bir ailenin tüm örneklerinin Göster/Oku örneklerine sahip olduğuna ikna etmek istemesidir. Bir basitleştirilmiş bir örnektir:
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
[mümkün olmadığını yorum olarak bahsedilen Birisi - teknik olarak imkansız bu çünkü (ve eğer öyleyse, neden) veya GHC uygulamasının sadece bir sınırlama?]
Bunu da istedim ama bildiğim kadarıyla bu mümkün değil. Sanırım sadece 1 sınıfa ihtiyacım var. – bennofs
Neden sadece parseF :: forall lt. (Oku (Anlaml lt), Göster (Translationm lt)) => SLiftedType lt -> String -> String'? Anladığım kadarıyla amacın için yeterli. –
@ AndrásKovács Motivasyon örneğime biraz daha içerik ekledim. '' SLiftedType lt'' değeri ön tanımlı değil - '' (String, String) '' '' (LiftedType, String) '' ve sonra '' (SLiftedType lt, Eşanlamlı lt) '', ancak '' SomeSing'' ifadesinde bağlı olarak yazılan kısmı saklıyorum. – dbeacham