Challenge 3: A Real Task Applicative Cannot Express — Possible Solution ==================================================================== -- A concrete example: looking up a user by ID, and THEN, only if that -- lookup succeeds, using the user's OWN email address (part of the -- result) to look up their most recent order. -- -- findUser :: Int -> Maybe User -- findOrderByEmail :: String -> Maybe Order -- -- -- What we WANT to write: -- findRecentOrder :: Int -> Maybe Order -- findRecentOrder userId = findOrderByEmail (email (findUser userId)) -- -- (ignoring the Maybe-unwrapping problem here for a moment) -- -- This cannot be expressed with Applicative alone, because <*>'s own -- type signature is: -- -- (<*>) :: f (a -> b) -> f a -> f b -- -- Both arguments to <*> must be ALREADY WRAPPED, INDEPENDENTLY, before -- <*> ever runs -- there's no point at which <*> is given access to -- the actual, unwrapped VALUE produced by the first computation, only -- to decide what to do based on it. findOrderByEmail needs the real -- String email address extracted from findUser's own successful -- result -- but that email only exists once findUser has ALREADY run -- and ALREADY succeeded, and Applicative's whole design assumes both -- sides can be built up independently, in advance, with no such -- dependency between them. -- -- Put differently: with Applicative, you can combine "the result of -- computation A" and "the result of computation B" using a plain -- function -- but you can never use the ACTUAL VALUE that A produced -- to decide what computation B even IS. That's exactly the gap -- Chapter 3's Monad closes, via >>=, which genuinely does hand the -- real, unwrapped result of one computation to a function that -- produces the next one. WHY THIS WORKS AS AN ANSWER ------------------------------ This gives a concrete, realistic example (chaining a lookup based on a previous lookup's own result) where a later step genuinely needs an earlier step's real value, and correctly traces the limitation back to <*>'s own type signature requiring both arguments to be independently wrapped in advance, matching the chapter's own stated Applicative-vs-Monad distinction.