Od czasu do czasu wpadam na ten problem i na koniec chciałem zapytać, czy istnieje wspólne rozwiązanie lub wzorzec. Czy można utworzyć zmienną typu w zagnieżdżonym kontekście, odwołując się do typu z zewnętrznego kontekstu? Na przykładHaskell Odwoływanie się do zmiennej typu
foo :: a -> ... -> ..
foo = ...
where bar :: a -> ...
Teraz bar
„s a
jest inna niż Foo a
. Zazwyczaj to jest to, czego chcę, ale czasami sprawia, że życie jest trudne, i muszę sprawić, aby były takie same. Użyłem brudnych sztuczek, aby zmusić kontroler do zunifikowania tych dwóch w przeszłości, ale czasami udaremnia się. Oto mój najnowszy przykład (funkcja Parsec), który zachęcił mnie do zadania tego pytania.
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 = ...
Funkcja convert
potrzebne typ, dlatego musiałem określić adnotacji :: P m Project
. Oznacza to jednak, że muszę również wprowadzić m
, który nie jest niestety taki sam, jak m
jak w sygnaturze funkcji. Do typu raporty Checker to z:
Nie można wywnioskować
Monad m1
wynikające ze stosowaniapEnum
z kontekstuMonad m
Czy istnieje sposób, aby odwoływać funkcja podpis na m
bez jakiegoś brzydkiego włamania? (Brzydka Hack byłoby wstawienie kodu manekin, który nie zostanie wykonany, ale istnieje tylko w celu ujednolicenia tych dwóch rodzajów).
Dzięki za wskazanie, że 'ScopedTypeVariables' dotyczy tylko sygnatur z jawnym' forall'. Nic dziwnego, że wydawało się, że prawie nigdy nie działało ... – Cirdec
To nie do końca prawda - 'ScopedTypeVariables' powoduje, że zmienne typu są określane w deklaracjach klas nawet bez' forall'. Może więc zmienić znaczenie wymyślonego programu Haskell 2010. – shachaf