Je suis en train de mettre en œuvre par exemple Applicative pour un tel type:exemple Applicative pour l'Etat - pour des flux de données
newtype State s a = State {runState :: s -> (a, s)}
J'ai quelques idées différentes pour (< *>) fonction. Une façon de mettre en œuvre qui me vient à l'esprit est
(<*>) :: State s (a -> b) -> State s a -> State s b
State f <*> State s = State $ do
(fa, fs) <- f
let (sa, ss) = s fs
return (fa sa, ss)
Ou
(<*>) :: State s (a -> b) -> State s a -> State s b
State f <*> State s = State $ do
(sa, ss) <- s
let (fa, fs) = f ss
return (fa sa, fs)
Lequel (ou fait même l'un d'eux) est correcte et pourquoi?
Ils sont tous les deux typecheck et ne diffèrent que par l'ordre des transformations "state". Je ne trouve pas de bonne raison de préférer l'un à l'autre ...
Cette question semble être une bonne occasion de [nerd snipe] (https://xkcd.com/356/). Voici une définition déroutante (mais valide!) De '>> =' pour une monade 'State' pour que vous pensiez à:' State f >> = g = État $ \ s -> let {(u, x) = ft; (t, y) = runState (g x) s} dans (u, y) '. Observez comment 'x',' y' vont de haut en bas mais 's',' t', 'u' vont de bas en haut. Toujours fait mal au cerveau :) –
Si vous ne l'avez pas vu, [vous pourriez aimer ça] (https://lukepalmer.wordpress.com/2008/08/10/mindfuck-the-reverse-state-monad/) – luqui
@BenjaminHodgson C'est bizarrement beau – 4castle