Applicative instance for State - order of data flow

Viewed 932

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

4 Answers

Well its depends upon State flow of Monad bind >>= as Applicative interchange law and its been pointed out in comment as well that

Applicative Interchange Law

If f is also a Monad, it should satisfy pure = return (<*>) = ap

mean if MonadState state flows from left to right, so should in applicative and vice versa.

but it does not means that applicative should depends upon monad implementation or do-notation it's incorrect as told by @leftaroundabout

Related