[ein Follow-up zu Gabriel Gonzalez Antwort]
Die richtige Schreibweise für Zwänge und Quantifizierungen in Haskell ist folgende:
<functions-definition> ::= <functions> :: <quantified-type-expression>
<quantified-type-expression> ::= forall <type-variables-with-kinds> . (<constraints>) => <type-expression>
<type-expression> ::= <type-expression> -> <quantified-type-expression>
| ...
...
Kinds entfallen, sowie forall
s werden für Rang-1-Typen:
<simply-quantified-type-expression> ::= (<constraints-that-uses-rank-1-type-variables>) => <type-expression>
zum Beispiel:
{-# LANGUAGE Rank2Types #-}
msum :: forall m a. Monoid (m a) => [m a] -> m a
msum = mconcat
mfilter :: forall m a. (Monad m, Monoid (m a)) => (a -> Bool) -> m a -> m a
mfilter p ma = do { a <- ma; if p a then return a else mempty }
guard :: forall m. (Monad m, Monoid (m())) => Bool -> m()
guard True = return()
guard False = mempty
oder ohne Rank2Types
(da wir nur Rang-1-Typen hier haben), und mit CPP
(j4f):
{-# LANGUAGE CPP #-}
#define MonadPlus(m, a) (Monad m, Monoid (m a))
msum :: MonadPlus(m, a) => [m a] -> m a
msum = mconcat
mfilter :: MonadPlus(m, a) => (a -> Bool) -> m a -> m a
mfilter p ma = do { a <- ma; if p a then return a else mempty }
guard :: MonadPlus(m,()) => Bool -> m()
guard True = return()
guard False = mempty
Das "Problem" ist, dass wir nicht
schreiben
class (Monad m, Monoid (m a)) => MonadPlus m where
...
oder
class forall m a. (Monad m, Monoid (m a)) => MonadPlus m where
...
Das heißt, forall m a. (Monad m, Monoid (m a))
kann als eigenständige Integritätsbedingung verwendet werden, kann aber nicht mit einer neuen einparametrigen Typenklasse für *->*
Typen aliasiert werden. Diese
ist, weil der Mechanismus wie defintion typeclass dies funktioniert:
class (constraints[a, b, c, d, e, ...]) => ClassName (a b c) (d e) ...
das heißt die rhs Seitentyp Variablen einführen, nicht auf die linke Skala oder forall
an den lhs.
Stattdessen brauchen wir 2-parametrischen typeclass schreiben:
{-# LANGUAGE MultiParamTypeClasses, FlexibleContexts, FlexibleInstances #-}
class (Monad m, Monoid (m a)) => MonadPlus m a where
mzero :: m a
mzero = mempty
mplus :: m a -> m a -> m a
mplus = mappend
instance MonadPlus [] a
instance Monoid a => MonadPlus Maybe a
msum :: MonadPlus m a => [m a] -> m a
msum = mconcat
mfilter :: MonadPlus m a => (a -> Bool) -> m a -> m a
mfilter p ma = do { a <- ma; if p a then return a else mzero }
guard :: MonadPlus m() => Bool -> m()
guard True = return()
guard False = mzero
Nachteile: wir zweite Parameter verwenden, jedes Mal wenn wir MonadPlus
angeben müssen.
Frage: wie
instance Monoid a => MonadPlus Maybe a
wenn MonadPlus
geschrieben werden kann, ist ein parametrischer typeclass?MonadPlus Maybe
von base
:
instance MonadPlus Maybe where
mzero = Nothing
Nothing `mplus` ys = ys
xs `mplus` _ys = xs
arbeitet Monoid Maybe
nicht mag:
instance Monoid a => Monoid (Maybe a) where
mempty = Nothing
Nothing `mappend` m = m
m `mappend` Nothing = m
Just m1 `mappend` Just m2 = Just (m1 `mappend` m2) -- < here
:
(Just [1,2] `mplus` Just [3,4]) `mplus` Just [5,6] => Just [1,2]
(Just [1,2] `mappend` Just [3,4]) `mappend` Just [5,6] => Just [1,2,3,4,5,6]
analogisch, forall m a b n c d e. (Foo (m a b), Bar (n c d) e)
gibt Anlass für (7-2 * 2) -parametric typeclass wenn wir *
Typen wollen, (7 - 2 * 1) -Param etric typeclass für * -> *
Typen und (7 - 2 * 0) für * -> * -> *
Typen.
Ich bin mir sicher, dass es hier eine interessante Frage gibt, in seiner jetzigen Form ist es im Wesentlichen "Welche Probleme haben edwardk und tekmo?" , die nur von diesen Leuten wirklich beantwortet werden können. Daher glaube ich nicht, dass diese Frage in ihrer jetzigen Form zu SO passt. – hammar
Ich scheint wie "welche Probleme existieren, denen jemand begegnet ist?" ist hier eher die Absicht. Jeder, der auf ähnliche Probleme gestoßen ist, könnte dies, wie ich erwarte, anerkennen und die Frage genauso gut ansprechen wie die spezifischen Personen, deren Beschwerden erwähnt werden. –
Ja, @C.A.McCann hat meine Absicht ziemlich gut erfasst, obwohl ich nicht besonders darauf bedacht bin, "auf welche Probleme sind Sie gestoßen?" so sehr wie "was ist das zugrunde liegende Problem?" Ich erwarte, dass eine gute Antwort darauf eingehen wird, was das derzeitige Zwangssystem * ist, was seine Schwächen sind und ob es Pläne gibt, es zu verbessern. –