In the authors enter first and last name example, isn’t the do notation also much clearer on order of effects? Eg being asked first for first name?
getPerson :: IO Person
getPerson =
Person
<$> (putStrLn "Enter your first name:" *> getLine)
<*> (putStrLn "Enter your last name:" *> getLine)
is transparently clear (to a seasoned Haskeller).https://hackage-content.haskell.org/package/async-2.2.6/docs...
newtype FlippedIO a = MkFlippedIO { runFlippedIO :: IO a }
deriving Functor
instance Applicative FlippedIO where
pure = MkFlippedIO . pure
liftA2 f (MkFlippedIO x) (MkFlippedIO y) =
MkFlippedIO ((flip . liftA2 . flip) f x y)
data Person = Person String String
deriving Show
putStrLnFlipped = MkFlippedIO . putStrLn
getLineFlipped = MkFlippedIO getLine
getPerson :: IO Person
getPerson = runFlippedIO $
Person
<$> (putStrLnFlipped "Enter your first name:" *> getLineFlipped)
<*> (putStrLnFlipped "Enter your last name:" *> getLineFlipped)
It runs things "backwards": ghci> getPerson
One
Enter your last name:
Two
Enter your first name:
Person "Two" "One"