8 ms·
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
by danidiaz 7y 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-haskell-code-more.html 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.
- nilkn 7y agoI'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.
- dllthomas 7y agoFor 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.