Hacker News new | ask | show | jobs
by danidiaz 2506 days ago
In your first version, I think I would use =<< to keep "flow" of information right-to-left. I also use parentheses instead of . and $ when there isn't a lot of nesting, I got that habit from this post about writing legible Haskell http://www.haskellforall.com/2015/09/how-to-make-your-haskel...

    getSocketAPIPort :: Int -> IO Int
    getSocketAPIPort defaultPort = do
        maybeEnvPort <- lookupEnv "socketPort"
        return (fromMaybe defaultPort (readMaybe =<< maybeEnvPort))
Keeping the pattern match instead of using "fromMaybe" wouldn't be a bad idea, either:

    getSocketAPIPort :: Int -> IO Int
    getSocketAPIPort defaultPort = do
        maybeEnvPort <- lookupEnv "socketPort"
        return (case readMaybe =<< maybeEnvPort of
            Nothing   -> defaultPort
            Just port -> port)
It makes the default value stand out a bit more.
2 comments

I've written a fair bit of Haskell, including some production software. Your second version here is my personal favorite of the variants proposed so far. It's the version I can look at and more or less instantly understand. I think sometimes folks go a little too far with using library functions to manipulate Maybe values -- not that `fromMaybe` is particularly onerous, but something about the structure of pattern matching just conveys information to my brain much faster.
For my part, for that logic I'd consider MaybeT. I don't like that a malformed environment variable gets the same treatment as a missing environment variable, though.