So, I know literally nothing about Haskell, and I would rate my knowledge of functional programming theory as 'beginner' at best, but I still get baffled every time when reading Haskell code that implements anything other than something trivial like a fibonacci sequence. The poker server code looks extremely tidy and well engineered, so that can't be the problem, but to me it's utterly incomprehensible. It seems like…
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…
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 action. Maybe... getSocketAPIPort :: Int -> IO Int
getSocketAPIPort defaultPort = fromMaybe defaultPort . (readMaybe = lookupEnv "socketPort"
That might be going too far. But maybe it's what I'd write. Just depends on how much I expect to make this more complicated in the future. This form has the simplest flow to read. I mean... it's dense. Really dense. But it has the fewest total things going on, and it neatly divides into three interesting parts, easily understood in isolation, plumbed together with two common combinators. But it's also pretty rigid in structure. If you ever want to add other sources for finding the port or change the priorities of them, that form would need to be totally rewritten, and probably would end up back in do notation.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.