Frage

Die Idee, dass die Standard-Monad Klasse fehlerhaft ist und dass es tatsächlich verlängern Functor oder Pointed schwimmt herum.

Ich behaupte nicht, dass es das Richtige ist, zu tun, sondern nehme an, dass man versuchte, es zu tun:

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

So weit so gut, aber dann, wenn zu verwenden do-Notation versuchen:

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

Der Compiler beschwert sich:

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

Frage:

Does do-Notation Arbeit nur für base:GHC.Base.Monad? Gibt es eine Möglichkeit, es funktioniert mit einer alternativen Monad Klasse zu machen?

Extra-Kontext:

Was ich wirklich tun möchte, ist ersetzen base:Control.Arrow.Arrow mit einer „generalisierten“ Arrow Klasse:

{-# 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')

Und dann verwenden Sie die Arrow der proc-Notation mit meiner Arrow Klasse, aber das nicht wie im Beispiel oben von do-Notation und Monad.

Ich werde meistens verwenden Either als mein Paar Typkonstruktor und nicht die (,) Typkonstruktor wie mit der aktuellen Arrow Klasse. Dies könnte ermöglichen, den Code von meinem Spielzeug RTS-Spiel (cabal install DefendTheKind) viel schöner zu machen.

War es hilfreich?

Lösung

Sie müssen die NoImplicitPrelude Erweiterung für volle rebindable Syntax, einschließlich do und proc. In diesem Fall Sie die folgende erhalten, unter anderen Sachen:

  

"Do" Notation übersetzt mit unabhängig von Funktionen (>> =), (>>) und scheitert, ist in ihrem Umfang (nicht die Prelude-Versionen). Listenkomprehensionen, mdo (Abschnitt 7.3.6, „Die rekursive do-Notation“) und parallele Anordnung Comprehensions, sind nicht betroffen.

Sie können auch einig Umgang mit Negation zwicken, Gleichheit, Literalwerte, und so weiter. Große Weise zu verschleiern Code!

P. S. - Wenn Sie vorhaben, die do Syntax, was SIGFPE Anrufe „parametrisierte Monaden erneut zu binden „ ist ein großer Spaß. Die gleiche Idee ist in category-extras unter Control.Monad.Indexed . Und ja, sie funktionieren mit rebindable Syntax trotz der völlig unterschiedlichen Art Signaturen!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top