Es específico notación hacer para “base: GHC.Base.Monad”?
Pregunta
La idea de que la clase Monad
estándar es errónea y que en realidad debería extenderse Functor
o Pointed
está flotando alrededor.
No estoy necesariamente afirmando que es lo que hay que hacer, pero supongamos que uno estaba tratando de hacerlo:
import Prelude hiding (Monad(..))
class Functor m => Monad m where
return :: a -> m a
join :: m (m a) -> m a
join = (>>= id)
(>>=) :: m a -> (a -> m b) -> m b
a >>= t = join (fmap t a)
(>>) :: m a -> m b -> m b
a >> b = a >>= const b
Hasta aquí todo bien, pero luego cuando se trata de hacer uso de la notación:
whileM :: Monad m => m Bool -> m ()
whileM iteration = do
done <- iteration
if done
then return ()
else whileM iteration
El compilador se queja:
Could not deduce (base:GHC.Base.Monad m) from the context (Monad m)
Pregunta:
Qué hace la notación de trabajo sólo para base:GHC.Base.Monad
? ¿Hay una manera de hacer que funcione con una clase Monad
alternativa?
contexto adicional:
Lo que realmente quiero hacer es sustituir base:Control.Arrow.Arrow
con una "generalizada" clase Arrow
:
{-# LANGUAGE TypeFamilies #-}
class Category a => Arrow a where
type Pair a :: * -> * -> *
arr :: (b -> c) -> a b c
first :: a b c -> a (Pair a b d) (Pair a c d)
second :: a b c -> a (Pair a d b) (Pair a d c)
(***) :: a b c -> a b' c' -> a (Pair a b b') (Pair a c c')
(&&&) :: a b c -> a b c' -> a b (Pair a c c')
Y a continuación, utilizar proc-notación del Arrow
con mi clase Arrow
, pero que falla al igual que en el ejemplo anterior de do-notación y Monad
.
Voy a usar su mayoría Either
como mi tipo de par constructor y no el tipo (,)
constructor como con la clase Arrow
actual. Esto podría permitir que el código de mi juguete juego RTS (cabal install DefendTheKind
) mucho más bonita.
Solución
Es necesario utilizar el NoImplicitPrelude extensión de la sintaxis completa rebindable, incluyendo do
y proc
. En ese caso, se obtiene lo siguiente, entre otras cosas:
notación "Do" se convierte utilizando cualesquiera que sean las funciones (>> =), (>>), y fallan, son de alcance (no las versiones Prelude). Las listas por comprensión, MDO (Sección 7.3.6, “El recursiva do-notación”), y por comprensión matriz paralela, no se ven afectadas.
También puede ajustar algunas de manipulación de la negación, la igualdad, valores literales, y otras cosas. Gran manera de código obfuscate!
p.s. - Si va a volver a enlazar la sintaxis do
, Lo que llama SIGFPE "mónadas parametrizados " son muy divertidos. La misma idea se encuentra disponible en category-extras
bajo Control.Monad.Indexed . Y sí, lo hacen el trabajo con la sintaxis rebindable, a pesar de las muy diferentes firmas de tipo!