Question

Après avoir lu (et écrémage certaines sections) papier de Wadler sur monades, j'ai décidé de travailler à travers le papier de plus près, la définition foncteur et instances pour chacun des applicatifs monades qu'il décrit. En utilisant le synonyme de type

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

Wadler utilise pour définir la monade de l'Etat, je donne les résultats suivants (en utilisant des noms connexes afin que je puisse les définir avec une déclaration newtype plus tard).

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)

Quand je passe à l'aide d'un constructeur de type dans une déclaration newtype, par exemple.

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

tout se désagrège. Tout est juste une légère modification, par exemple,

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))

cependant rien à court GHC en raison du fait que l'expression lambda est caché dans ce constructeur de type. Maintenant, la seule solution que je vois est de définir une fonction:

isntThisAnnoying s (S m) = m s

, afin de se lier à s 'st' et retrouver en fait une valeur, par ex.,

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

Y at-il une autre façon de faire qui n'utilise pas ces fonctions auxiliaires?

Était-ce utile?

La solution

Si vous regardez , vous verrez qu'ils définissent ainsi:

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

de manière à donner le lambda interne un nom.

Autres conseils

La manière habituelle est de définir newtype newtype S a = S {runState : State -> (a, State)}. Alors, au lieu de votre isntThisAnnoying s (S m) vous pouvez écrire runState t st est le même que S m.
Vous devez utiliser un newtype car synonymes de type ne peuvent pas être des instances classe de types.

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