Frage

Nach dem Lesen (und einige Abschnitte von Skimming) Wadler Arbeit über Monaden, entschied ich mich an die Arbeit durch das Papier stärker, definieren Funktors und applicative Instanzen für jede der Monaden er beschreibt. Unter Verwendung des Typs Synonym

type M a = State -> (a, State)
type State = Int

Wadler verwendet den Zustand Monade zu definieren, ich habe den folgenden (mit einem damit verbundenen Namen, damit ich sie mit einer newtype Deklaration definieren kann 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 wechsle einen Typkonstruktor in einer newtype Erklärung zu verwenden, z. B.

newtype S a = S (State -> (a, State))

alles auseinander fällt. 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))

aber nichts läuft in GHC 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 zu binden s 'st' und tatsächlich einen Wert zurückgeben, z. B.

fmap f m = S (\st -> let (a, s) = isntThisAnnoying st m in (f a, s))

Gibt es eine andere Möglichkeit, dies zu tun, die nicht diese Hilfsfunktionen nicht verwendet?

War es hilfreich?

Lösung

Wenn Sie schauen hier , werden Sie sehen, dass sie es auf diese Weise zu definieren:

newtype State s a = State { runState :: (s -> (a,s)) }

, um die innere Lambda einen Namen zu geben.

Andere Tipps

Der üblicher Weg ist newtype newtype S a = S {runState : State -> (a, State)} zu definieren. Dann statt Ihrer isntThisAnnoying s (S m) können Sie runState t s schreiben, wo t die gleiche wie S m ist.
Sie haben eine newtype zu verwenden, da Typ Synonyme nicht typeclass Instanzen sein kann.

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