4 ms·
Applicative operators effect from left to right. So the order of effects in getPerson :: IO Person getPerson = Person <$> (putStrLn "Enter your f
by throwway262515 6mo ago
Applicative operators effect from left to right. So the order of effects in
getPerson :: IO Person
getPerson =
Person
<$> (putStrLn "Enter your first name:" *> getLine)
<*> (putStrLn "Enter your last name:" *> getLine)
is transparently clear (to a seasoned Haskeller).
- kccqzy 6mo agoThat’s only true when you use the IO monad as an Applicative. It’s not true if you use for example the Concurrently type from the async package (which is quite wonderful btw). The ApplicativeDo language extension makes it possible for you to use do notation in this case as well. https://hackage-content.haskell.org/package/async-2.2.6/docs/Control-Concurrent-Async.html#t:Concurrently https://hackage-content.haskell.org/package/async-2.2.6/docs...
- throwway262515 6mo agoDo you have a concrete example using Concurrently where the effect semantics is harder to understand--possibly even misleading--with effect combinators than with do notation?
- kccqzy 6mo agoWhen you use Concurrently you are implying that you want things to happen concurrently and you don’t care about effect ordering. You leave the effect ordering to the GHC runtime in how it schedules these green threads. Using do notation here works but it is slightly misleading. A seasoned Haskeller would never see do notation and assume anything about the ordering of effects.
- tome 6mo agoHere's a silly but simple example: 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"