Live data from Hacker News

Show HN: I built a poker site with Haskell

github.com

61–70 of 121 posts

Re: Show HN: I built a poker site with Haskell

#62
post #8

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…

It's some time since I last worked in Haskell (and I never worked on anything useful), but I would write the function this way: getSocketAPIPort :: Int -> IO Int getSocketAPIPort defaultPort = do maybeEnvPort defaultPort Just port -> fromMaybe defaultPort (readMaybe port)

100% this is how I'd write it (except probably with pure instead of return). I don't get the desire to sprinkle bind throughout the other replies in this thread. I feel like it makes things less clear.

Re: Show HN: I built a poker site with Haskell

#63

What would be the best IDE/editor for Haskell?

I tried spacemacs with intero for a while, but I'm now using https://github.com/haskell/haskell-ide-engine + vscode + vimmode. Mostly because I'm using vscode in my work and I don't want to invest more into emacs.

I use the exact same setup and like it a lot.

Re: Show HN: I built a poker site with Haskell

#64

What would be the best IDE/editor for Haskell?

Emacs works very well. Haskell is the second best emacs experience I've ever had, second only to Lisp.

Things were not always this way. Just a few years ago, it was a bad experience, so if you have bad memories, it may be time to try again.

Re: Show HN: I built a poker site with Haskell

#65

Earlier quoted context omitted.

Is it? There's no part of you that looks and that and wonders why it's stuffing return into every leaf of a branching structure instead of just leaving it at the root? That's just objectively redundant. And there's no part of you that's wondering why it's using nested branches to implement the railway oriented programming pattern? That's just objectively more convoluted than using the combinators that abstract that o…

> So yes, there is an additional burden in understanding my versions of the code. But that burden amortizes very nicely over a lifetime of getting the advantages of having all that plumbing just there when you need it. I definitely didn't argue this point (although I admit to skepticism). It sounds like you're actually aware that it's easier to read the redundant code when you are not an expert, so we don't have any…

> It sounds like you're actually aware that it's easier to read the redundant code when you are not an expert, so we don't have any disagreement there.

Actually, there is minor disagreement. I don't think I used anything requiring expert-level understanding. I would put the tools I used at the level of day-to-day proficiency, not expert level. Roughly, the level it took me 3 months to reach, not the level I'm still working towards after 10 years.

Re: Show HN: I built a poker site with Haskell

#66

Earlier quoted context omitted.

Unfortunately, a lot of work there is done by the Haskell community having utterly absurd standards for those things. I work in a different functional programming language, and you would not believe the amount of time I spend convincing new hires with Haskell backgrounds to spend the extra few characters to expand out the unreadable point-free/single-character-names style that Haskell folks prefer.

Has it ever occurred to you that Haskell programmers prefer single-letter variable names in some contexts because it makes the code better? Perhaps it is not the children who are wrong.

By the comment, the GP is not a Haskell developer and those people are not programming in Haskell.

So, even though it is well known that short named variables and point free syntax often improve the readability of Haskell code, it probably does not improve the readability of his code.

Re: Show HN: I built a poker site with Haskell

#67
post #8
post #2

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…

in python:

  def getSocketAPIPort(defaultport):
       try:
           return os.environ["socketPort"]
       except KeyError:
           return defaultport

Re: Show HN: I built a poker site with Haskell

#68
post #8

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…

in python: def getSocketAPIPort(defaultport): try: return os.environ["socketPort"] except KeyError: return defaultport

Close, but values from os.environ are always string, and not guaranteed to be parsable numbers.

Re: Show HN: I built a poker site with Haskell

#70

Earlier quoted context omitted.

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…

In your first version, I think I would use = http://www.haskellforall.com/2015/09/how-to-make-your-haskel... getSocketAPIPort :: Int -> IO Int getSocketAPIPort defaultPort = do maybeEnvPort Keeping the pattern match instead of using "fromMaybe" wouldn't be a bad idea, either: getSocketAPIPort :: Int -> IO Int getSocketAPIPort defaultPort = do maybeEnvPort defaultPort Just port -> port) It makes the default value stan…

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.
Post reply on HN