Używam operational monad przez Heinricha Apfelmusa. Chciałbym sparametryzować interpreter z monadą dla typu wyniku. Poniższa wersja mojego kodu kompiluje:Monada operacyjna z tłumaczem w dowolnej monadzie
{-# LANGUAGE GADTs #-}
import Control.Monad.Operational
data EloI a where
Display :: Int -> EloI()
type Elo a = Program EloI a
interpret :: Monad m => (Int -> m())
-> Elo a
-> Int
-> m a
interpret display = interp
where
interp :: Monad m => Elo a -> Int -> m a
interp = eval . view
eval :: Monad m => ProgramView EloI a -> Int -> m a
eval (Display i :>>= is) s = interp (is()) s
Teraz zmienić ostatni wiersz do
eval (Display i :>>= is) s = display i >> interp (is()) s
i typu wnioskowania nie uda już, mam wyjście
nie mógł dedukuj (m ~ m1) z kontekstu (Monad m)
związany podpisem typu do interpretacji :: Monad m => (Int -> m()) -> Elo a -> Int -> ma (.. .)
Po usunięciu podpisu typu dla interp, otrzymuję dodatkowy błąd (nie mógł wydedukować (a1 ~ a)).
Kiedy zmieniam wszystkie m na IO (jak w przypadku tic tac toe dla monady operacyjnej), to kompiluje się ponownie.
Czy próbuję czegoś, co nie ma sensu, czy mogę podać wskazówkę do GHC? Muszę przyznać, że nie jestem pewien, czy potrzebuję tej elastyczności.
nawet nie próbować a) (althaugh I zazwyczaj nie korzystają z podpisami typu lokalnych), ponieważ poniższej instrukcji w przykładowym kodzie "Należy pamiętać, że ponieważ ProgramView jest GADT, adnotacja typu dla eval jest obowiązkowa." – Duschvorhang