Earlier quoted context omitted.
Haskell is dense. I'm picking it up now[0], so this project was very useful for me to see how some "real world" Haskell is written. But yes, take for example this function getSocketAPIPort :: Int -> IO Int getSocketAPIPort defaultPort = do maybeEnvPort return defaultPort Just port -> maybe (return defaultPort) return (readMaybe port) It gets a port from an environment variable, if it can, otherwise a default port. Co…
Ouch. That function is actually written in a pretty convoluted and redundant way. getSocketAPIPort :: Int -> IO Int getSocketAPIPort defaultPort = do maybeEnvPort >= readMaybe That's starting to border on over-terse, so you could expand the bind operator into do notation if you wanted to spread it out a bit further. On the other hand, it's also starting to feel over-verbose, using do notation for only a single IO act…
return . fromMaybe defaultPort $ maybeEnvPort >>= readMaybe
Basically this is composing a function out of "return" and "fromMaybe" (using the composition operator "."), then partially applying defaultPort to that composed function, so you now have a function that takes one argument. The resulting function is then applied (using $) to the result of "maybeEnvPort >>= readMaybe".In "maybeEnvPort >>= readMaybe", ">>=" is an infix function that takes maybeEnvPort as its first argument (which is a Maybe Monad), "unpacks" it, applies "readMaybe" to the unpacked result. readMaybe returns another Maybe Monad.
The result of everything after the $ is a Maybe Monad that contains the port from the environment, or a failure condition. The result of applying the composed-and-partially-applied function (from before the $) to it is that the port from the environment is chosen if it didn't fail, otherwise the defaultPort is used, and then the whole thing is wrapped in an IO Monad.