Domanda

L'idea che la classe Monad standard viene viziata e che dovrebbe in realtà estendere Functor o Pointed è galleggianti intorno.

Non sto necessariamente sostenendo che è la cosa giusta da fare, ma supponiamo che si stava cercando di farlo:

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

Fin qui tutto bene, ma poi quando si cerca di fare uso notazione:

whileM :: Monad m => m Bool -> m ()
whileM iteration = do
    done <- iteration
    if done
        then return ()
        else whileM iteration

Il compilatore si lamenta:

Could not deduce (base:GHC.Base.Monad m) from the context (Monad m)

Domanda:

fa fare notazione lavoro solo per base:GHC.Base.Monad? C'è un modo per farlo funzionare con una classe Monad alternativa?

contesto Extra:

Quello che voglio veramente fare è sostituire base:Control.Arrow.Arrow con un "generalizzato" classe 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')

e quindi utilizzare proc notazione del Arrow con la mia classe Arrow, ma che non riesce, come nel precedente esempio di fai-notazione e Monad.

Userò lo più Either come il mio tipo di coppia di costruzione e non il tipo (,) costruttore come con la classe Arrow corrente. Ciò potrebbe consentire di rendere il codice del mio giocattolo gioco RTS (cabal install DefendTheKind) molto più bella.

È stato utile?

Soluzione

È necessario utilizzare il NoImplicitPrelude estensione per la piena sintassi rebindable, tra cui do e proc. In questo caso, si ottiene quanto segue, tra le altre cose:

  

notazione "Do" è tradotto usando qualsiasi funzione (>> =), (>>), e non riescono, sono di portata (non le versioni Prelude). list comprehension, MDO (Sezione 7.3.6, “Il ricorsiva do-la notazione”), e comprensioni di array paralleli, sono inalterati.

È anche possibile modificare alcuni trattamenti dei negazione, l'uguaglianza, valori letterali, e quant'altro. Ottimo modo per codice Oscurazione!

P.S. - Se avete intenzione di associare nuovamente la sintassi do, quali chiamate SIGFPE "monadi parametrizzati " sono molto divertenti. La stessa idea è disponibile in category-extras in Control.Monad.Indexed . E sì, lo fanno il lavoro con la sintassi rebindable, nonostante le selvaggiamente diverse firme di tipo!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top