Applicative instance for public data flow

I am trying to implement an applicative instance for this type:

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

I have different ideas for the function (<*>). One way to realize it that comes to my mind is to

(<*>) :: 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 even any of them) is correct and why?

They are both typecheck and differ only in the order of state conversion. I can not find good reason to prefer one after another ...

+4
source share
3 answers

, , , . - , . , - : , <*> . IO, ,

(,) <$> readLn <*> getLine :: IO (Int, String)

Int, . .

+4

. , :

x <*2> y = flip ($) <$> y <*1> x

, , "" . , .

+4

-, (monadic!) do , , . :

State f <*> State s = State $ \q
     -> let (fa, fs) = f q
            (sa, ss) = s fs
        in (fa sa, ss)

State f <*> State s = State $ \q
     -> let (fa, fs) = f ss
            (sa, ss) = s q
        in (fa sa, fs)

It also makes it clear that in the applicative instance there is no internal evaluation order (as opposed to the monad instance).

+4
source

Source: https://habr.com/ru/post/1681647/


All Articles