Pregunta. ¿Hay alguna forma de hacer que este código funcione sin una firma de tipo explícita?Inferencia de tipo GHC infortunios
Código. En primer lugar, tengo una clase alterna MonadTrans
en la práctica, mucho más agradable, inspirada en Data.Newtype
. Parece que este,
{-# LANGUAGE FlexibleContexts, TypeFamilies #-}
module Alt.Control.Monad.Trans where
import Control.Monad
class (Monad , Monad (BaseMonad)) => MonadTrans (:: * -> *) where
type BaseMonad :: * -> *
lift :: (BaseMonad) α -> α
Entonces, tengo una clase A
con el método foo
, y si alguna mónada base de M
es un A
, entonces cualquier mónada transformado T M
es también un A
. En el código,
class A where
foo :: String -> ()
instance (A (BaseMonad), MonadTrans) => A where
foo n = lift $ foo n
Sin embargo, si ahora quiero crear un acceso directo para foo
con su primer argumento sustituido, entonces necesito una firma de tipo explícita o desbordamientos de pila contexto del compilador.
minimize_call :: A => ()
minimize_call = foo "minimize"
información posible para ayudar a la inferencia. Digamos que tenemos un tipo asociado B :: * -> *
. Estoy pensando que quiero decir que el compilador B
satisface B t /= t
, B (B t) /= B t
, etc. es decir B
es de alguna manera "monotónico" - que perseguir tipos asociados es equivalente a eliminar newtype wrappers, y debe saber que no puede eliminar newtype wrappers para siempre , por lo tanto, es necesario agregar el contexto A
a la firma.
lo siento, debería haberme molestado en recordar _por qué_ cambié a la alternativa 'MonadTrans' ... por ahora, digamos que produce código más limpio, pero creo que había una razón más importante. – gatoatigrado
Pregunta interesante. ¿Por qué no quieres una firma tipográfica explícita? No 'minimize_call' tiene que ser un valor fijo, no una constante polimórfica (¿o puede que sea polimórfico, no estoy seguro)? Si tiene algún tipo único fijo, preferiría documentarlo, y si no lo hace, preferiría documentar ** que **. Obligar al lector a hacer un análisis completo del programa en su cabeza para descubrir qué tipo 'minimize_call' parece un poco contraproducente. – Ben
@Ben, es cierto que, en este caso, tener una firma de tipo para 'minimize_call' es una buena práctica.Sin embargo, si se rompe la inferencia de tipo sugiere que algo va mal (con el diseño, el compilador o la comunicación con el compilador) y es probable que cause problemas, sin mencionar los mensajes de error ininteligibles. – gatoatigrado