|
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 <- lookupEnv "socketPort"
case maybeEnvPort of
Nothing -> 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. Conceptually, this is easy to understand, but translating your understanding of that process to Haskell is not 1 to 1. For example, the last line alone: Just port -> maybe (return defaultPort) return (readMaybe port)
You have to understand Maybe (and failure contexts), you have to understand that "return" does not return from a function like typical imperative languages, instead it wraps a type in a Monad (in this case, the IO Monad), and you also have to understand that most of those things on that line, including the "return" function, are parameters to the "maybe" function.There's a lot to understand in terms of the underlying machinery of Haskell to be able to read its cryptic flow and syntax. But it is worth it imo. 0. http://learnyouahaskell.com |
But in every case, all the various return calls should be combined into one (or none, if you use fmap or <$>), and the fallback to the default should only be written once.