Domanda. C'è un modo per far funzionare questo codice senza una firma di tipo esplicita?Guai di inferenza del tipo di GHC
Codice. Innanzitutto, ho una classe alternativa allo MonadTrans
alternativa molto più bella, ispirata allo Data.Newtype
. Ecco come si presenta,
{-# LANGUAGE FlexibleContexts, TypeFamilies #-}
module Alt.Control.Monad.Trans where
import Control.Monad
class (Monad , Monad (BaseMonad)) => MonadTrans (:: * -> *) where
type BaseMonad :: * -> *
lift :: (BaseMonad) α -> α
Poi, ho una classe A
con il metodo foo
, e se alcuni di base monade M
è un A
, allora ogni monade trasformato T M
è anche un A
. Nel codice,
class A where
foo :: String -> ()
instance (A (BaseMonad), MonadTrans) => A where
foo n = lift $ foo n
Tuttavia, se ora voglio creare un collegamento per foo
con il suo primo argomento sostituito, quindi ho bisogno di una firma di tipo esplicito, o stack overflow contesto del compilatore.
minimize_call :: A => ()
minimize_call = foo "minimize"
Possibili informazioni per aiutare l'inferenza. Diciamo che abbiamo un tipo associato B :: * -> *
. Sto pensando che voglio dire al compilatore B
soddisfa B t /= t
, B (B t) /= B t
, ecc. Cioè B
è in qualche modo "monotono" - che inseguire tipi associati equivale a rimuovere i wrapper newtype, e dovrebbe sapere che non può rimuovere per sempre i wrapper newtype , quindi aggiungere il contesto A
alla firma è necessario.
scusa, mi sarei preso la briga di ricordare _why_ Sono passato al "MonadTrans" alternativo ... per ora, diciamo che produce codice più pulito, ma penso che ci fosse un motivo più sostanziale. – gatoatigrado
Interessante domanda. Perché non vuoi una firma di tipo esplicita? Il parametro 'minimize_call 'non deve essere un valore fisso, non una costante polimorfica (o forse si può ottenere che sia polimorfico, non ne sono sicuro)? Se ha un singolo tipo fisso, preferirei documentarlo e, in caso contrario, preferirei documentare ** **. Costringere il lettore a fare l'intera analisi del programma nella sua testa per capire che tipo "minimizza_call" sembra un po 'controproducente. – Ben
@Ben, È vero che, in questo caso, avere una firma di tipo per 'minimize_call' è una buona pratica.Tuttavia, l'inferenza del tipo che si interrompe suggerisce che qualcosa non funziona (con il design, il compilatore o la comunicazione con il compilatore) e probabilmente causerà problemi, per non parlare di messaggi di errore incomprensibili. – gatoatigrado