Hacker News new | ask | show | jobs
Haskell: Monoid (Use Case Example) (cstml.github.io)
3 points by cstml 1868 days ago
2 comments

Haskell is nice, it's type systems allows the developer to prove the properties of their algorithm.

But it's so hard to read when you're not used to the syntax, compare this to a Javascript/Typescript solution:

  const conds = [
    i => i % 2 === 1,
    i => i % 4 === 0,
    i => i % 6 === 0
  ]
  [1, 2, 3].map(i => conds.every(f => f(i)))
Any developer with any language background should be able to understand this.

But `foldl1 (||) (map ($x) tests)` is gibberish when you don't know the Haskell syntax.

Maybe that's why the entry level to Haskell is so high.

Indeed, but arguably both can sound strange to an outsider.

Much of the minimal elegance of Haskell relies on it being able to express logic while abstracting away details. If the goal was to get the syntax to look more like the one of JS/TS, there could have been a way to write it similarly to your example - and even simpler. But the point was - show how the use of a monoid abstracts all that - allowing one to simply use the already defined operations of the monoid.

At the time the exaples were written, they were indeed intended for a Haskell crowd, but good point going forward. Thank you.

I don't know, I hear this argument a lot, but it does not make any sense to me. With `foldl1 (||) (map ($x) tests)`, my guess is that I am folding an operation denoted by || (my guess is or?) over some sort of collection that was obtained by mapping some function denoted by $x over what must be another collection called tests. I have been staring at the javascript example for like 5 minutes and I think I know what it does, but I am still confused by it.
`every()` returns true if every item in a collection verify a predicate (this is the `foldl1 (||)` part of the example).

`map()` applies a function to every item in a collection and returns a new collection.

What I confuses me about the Haskell example is `$x`. Where does it come from? why isn't it referenced anywhere afterwards? Is the `$` an operator of some sort that names a variable in the later block? Why is it `tests` and not `$tests` then?

`($x)` could equivalently have been written `\f -> f x`, which would have been a bit clearer.

In general in Haskell if you have an infix operator `OP` then `(OP x)` means the same thing as `\y -> y OP x`. (Additionally in this case you need to know that `$` is defined by `f $ x = f x`.)

Thank you for your clarification.

And I just re-read my example in JS and I've made a TERRIBLE mistake ^^

`.every()` would be `foldl1 (&&)`, I would need `.some()` instead to have the correct behavior.

I wrote this small post on a use case of the Monoid typeclass in Haskell.