Question

L'idée que la classe standard Monad est erronée et qu'elle devrait étendre effectivement Functor ou Pointed est flottant autour.

Je ne prétends pas nécessairement qu'il est la bonne chose à faire, mais supposons que l'on essayait de le faire:

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

Jusqu'à présent, si bon, mais en essayant d'utiliser faire la notation:

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

Le compilateur se plaint:

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

Question:

fonctionne-t-do-notation seulement pour base:GHC.Base.Monad? Est-il un moyen de le faire fonctionner avec une classe Monad alternative?

Contexte supplémentaire:

Ce que je veux vraiment faire est de remplacer base:Control.Arrow.Arrow par un « généralisé » 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')

Et puis utilisez proc notation du Arrow avec ma classe Arrow, mais qui ne parvient comme dans l'exemple ci-dessus do notation et Monad.

Je vais utiliser la plupart du temps Either comme mon constructeur de type paire et non le constructeur de type (,) comme avec la classe actuelle de Arrow. Cela pourrait permettre de rendre le code de mon jouet jeu RTS (de cabal install DefendTheKind) beaucoup plus joli.

Était-ce utile?

La solution

Vous devez utiliser le Extension NoImplicitPrelude syntaxe complète rebindable, y compris do et proc. Dans ce cas, vous obtenez ce qui suit, entre autres choses:

  

notation "Do" est traduit en utilisant quelles que soient les fonctions (>> =), (>>), et l'échec, sont une portée (pas les versions Prelude). Liste compréhensions, MDO (Section 7.3.6, « Le do-notation récursive ») et matrice parallèle compréhensions, ne sont pas affectés.

Vous pouvez également modifier une manipulation de la négation, l'égalité, les valeurs littérales, et ainsi de suite. Un excellent moyen de coder obfuscate!

p.s. - Si vous allez rebind la syntaxe do, ce que monades des appels sigfpe « paramétrées « sont très amusant. La même idée est disponible en category-extras sous Control.Monad.Indexed . Et oui, ils fonctionnent avec la syntaxe rebindable, malgré les signatures de type très différentes!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top