> In the case above, I'd pass a function which maps a (pure) date and string into a (pure) bool, to test for EU membership.
i doubt you could make (or really, even want to make) `checkEUMembership` pure, I'm guessing it'd involve a DB lookup of some kind.
in general, you can't always "pull out all the IO" into an only-pure-logic "core"; like if you want to look up one thing and then look up another thing based on the result of the first lookup. and that's okay!
i'm not going to write a whole monad tutorial, but using an `IO Foo` is kind of like using a `Promise<Foo>`¹; you do stuff like this (in JS syntax):
getX(...).then((x) =>
getYForX(x).then((y) =>
foo(x, y)
// note - nested lambdas/closures, `x` is closed-over
)
)
"do-notation" lets you avoid callback hell, similarly to async/await.
---
¹ Unfortunately, JS's Promise#then mixes two things:
• "dirtying" a pure function:
getNumberFromDB().then((x) => x*2)
which in Haskell would use
fmap :: (a -> b) -> IO a -> IO
• piping the result into another side-effecting function:
getNumberFromDB().then((x) =>
getNameForNumberFromDB(x)
)
which in Haskell would use the "bind" operator:
(>>=) :: IO a -> (a -> IO b) -> IO b