Bazen bu problemle karşılaşıyorum ve sonunda ortak bir çözüm ya da model olup olmadığını sormak istedim. İç içe geçmiş bir bağlam başvurusunda bir tür değişkeni bir dış bağlamdan tür yapmak mümkün mü? Örneğin,Haskell Bir Tür Değişkeni Referansı
foo :: a -> ... -> ..
foo = ...
where bar :: a -> ...
Şimdi bar
'ın a
foo a
farklıdır. Tipik olarak bu benim istediğim şey, ama bazen hayatı zorlaştırıyor ve onları aynı şekilde yapmaya ihtiyacım var. Geçmişte ikiyi birleştirmek için tip denetçisini zorlamak için kirli numaralar kullandım, ancak bazen engellenirim. İşte en son örneğim (Parsec işlevi) beni bu soruyu sormak için beni teşvik etti.
data Project = ... deriving Enum
data Stuff = ...
pProject :: Monad m => P m Stuff
pProject = do
stuff <- pStuff
...
convert stuff <$> pEnum :: P m Project
pEnum :: (Monad m, Enum a) => String -> P m a
pEnum = ...
convert
işlevi dolayısıyla ben ek açıklama :: P m Project
belirtmek zorunda türü gerekli. Ancak, bu, m
'u tanıtmam gerektiği anlamına geliyor, bu da maalesef aynı imzanın m
işlev imzasıyla aynı değil. tip denetleyicisi raporları, bu şununla:
bağlamda
Monad m
den pEnum
bir kullanımından kaynaklanan Monad m1
anlamak Could işlev imzası en m
bazı çirkin kesmek olmadan başvurmak için bir yol var mı? (Çirkin bir hack, çalıştırılamayacak, ancak yalnızca iki türü birleştirmek için var olan kukla kod ekliyor olurdu.)
'ScopedTypeVariables' yalnızca açık bir 'forall' olan imzalar için geçerli olduğuna dikkat ettiğiniz için teşekkür ederiz. Hiç şüphe yok ki neredeyse hiç işe yaramadı ... – Cirdec
Bu tam olarak doğru değil - 'ScopedTypeVariables', forall 'olmadan bile sınıf bildirimlerinde belirtilen tip değişkenleri yapar. Bu nedenle, bir mahvolmuş Haskell 2010 programının anlamını değiştirebilir. – shachaf