I am trying to implement Applicative instance for such a type:
newtype State s a = State {runState :: s -> (a, s)}
I have some different ideas for (<*>) function. One way to implement it that comes to my mind is
(<*>) :: 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)
Or
(<*>) :: 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)
Which one (or does even any of them) is correct and why?
They both typecheck and differ only by "state" transformations order. I cannot find any good reason to prefer one over another...
>>=
for aState
-like monad for you to think about:State f >>= g = State $ \s -> let { (u, x) = f t; (t, y) = runState (g x) s } in (u, y)
. Observe howx
,y
go from top to bottom buts
,t
,u
go from bottom to top. Still makes my brain hurt :) – Almontedo
blocks in this question are in "functions" monad.do { z <- f; y <- g; return (z y) } = \x -> let {z = f x; y = g x } in (const $ z y) x
, ifff :: a -> b
for somea, b
. (just making this comment below more easily noticeable). – Graham