Nachdem ich Wadlers Aufsatz über Monaden gelesen und einige Abschnitte über Monaden gelesen hatte, beschloss ich, die Arbeit genauer zu durcharbeiten, indem ich Funktoren und anwendbare Instanzen für jede der beschriebenen Monaden definierte. Unter Verwendung des Typs SynonymFunctor/Applicative Instanzen für Staat in Haskell
type M a = State -> (a, State)
type State = Int
Wadler verwendet den Zustand monadisch zu definieren, I haben die folgenden (mit einem damit verbundenen Namen, damit ich sie mit einer newtype Erklärung definieren später).
fmap' :: (a -> b) -> M a -> M b
fmap' f m = \st -> let (a, s) = m st in (f a, s)
pure' :: a -> M a
pure' a = \st -> (a, st)
(<@>) :: M (a -> b) -> M a -> M b
sf <@> sv = \st -> let (f, st1) = sf st
(a, st2) = sv st1
in (f a, st2)
return' :: a -> M a
return' a = pure' a
bind :: M a -> (a -> M b) -> M b
m `bind` f = \st -> let (a, st1) = m st
(b, st2) = f a st1
in (b, st2)
Wenn ich Schalter einen Typkonstruktor in einer newtype Erklärung unter Verwendung beispielsweise
newtype S a = S (State -> (a, State))
alles fällt auseinander. Alles ist nur eine leichte Modifikation, zum Beispiel,
instance Functor S where
fmap f (S m) = S (\st -> let (a, s) = m st in (f a, s))
instance Applicative S where
pure a = S (\st -> (a, st))
jedoch nichts in GHC läuft aufgrund der Tatsache, dass der Lambda-Ausdruck in diesem Typkonstruktor verborgen ist. Nun ist die einzige Lösung, die ich sehe, ist eine Funktion zu definieren:
isntThisAnnoying s (S m) = m s
um s ‚st‘ zu binden und tatsächlich einen Wert zurückgeben, zB
fmap f m = S (\st -> let (a, s) = isntThisAnnoying st m in (f a, s))
Gibt es eine andere Möglichkeit, dies zu tun das verwendet diese Hilfsfunktionen nicht?
Das bedeutet auch 'runState = flip isntThisAnnoying'. – kennytm
Okay - während eine Hilfsfunktion noch benötigt wird, könnte ich einfach den Typ mit einem Datensatz definieren, um die Funktion kostenlos zu bekommen. Was Sie sagen, ist, dass es keine Möglichkeit gibt, Funktionen wie 'runState' oder 'run' zu vermeiden. Vielen Dank. – danportin
Wenn es Ihnen weh tut, es als eine Funktion zu betrachten, denken Sie stattdessen an einen Struct Field Accessor. :-) –