Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Everyone is like "Haskell is such a cool language, it's so much more clear concise and understandable than that stupid language you like so much" (their words, not mine). Then you ask them how they write `foo.bar.baz = 1` and you get 50k words of documentation, 113 new operators[1] like `<<<>~`, and a library with 20 new dependencies. I make fun of them only because I love them - I think Haskell has brought us a lot of cool things like Maybe and Either - but how has no one ever taken a step back and gone "wow, this seems a tad complex for what we're trying to accomplish"?

[1]: I'm not even exaggerating - https://hackage-content.haskell.org/package/lens-5.3.5/docs/...



Because foo.bar.baz = 1 has a side-effect, and side-effects, though powerful, are extremely prone to error. Lenses take more effort, but give us the same amount of power without all the errors. Many people believe the trade-off is worthwhile.


immer.js allows you to do foo.bar.baz = 1 without side effects.


Thanks, I just took a look. It works by relaxing constraints to allow mutation on a “draft” copy of the data. Interesting idea! (But verboten in Haskell, of course.)


But there's nothing 'verboten' about this in Haskell! Haskell could allow for the exact same syntax, and do the exact same thing behind the scenes. Oh but no, LENSES of course, you must rewrite obvious code in the most obtuse manner possible. :)


Unlike JavaScript, it would require fundamental changes to the language itself, so I don’t think it’s really a fair comparison.


But lenses already do the same thing, just with a worse syntax. do notation already rewrites a lot of messy Haskell into cleaner Haskell. It's not that different!


I just want one good monad tutorial that doesn't mention haskell. Just one.


A monad is just a flatmappable. The end. That's the whole tutorial. If you're coming from JS/TS and know how to construct a singleton array and can use Array.prototype.flatMap, you already can do monads. Anything else "monadic" is not a monad. It's a property of something else that can be derived from what I wrote above, OR it's a property of one specific monad not monads in general.

A monad is a flatmappable.

A monad is a flatmappable.

A monad is a flatmappable.


It doesn't cover monad transformers though.


Why would a definition of a monad need to define "monad transformer"? THat's like saying "your definition of "class" needs to cover "object mapper"


Monads are a set of annotated functions or methods that participate in shared encapsulating middleware. It's kind of like writing an interpreter for existing code by changing shape of the inputs, outputs, and possibly even flow control of the execution of those functions -- but without writing an interpreter.

The easiest example would be something like wrapping a bunch of arithmetic operations with a "cumulative" monad. Effectively this changes your add, sub, mul, div functions such that instead of taking 2 floats and returning a float, they take a hashmap and return a hashmap. The hashmap consists of the original args as well as the cumulative total, for whatever reason. The details of the hashmap are hidden from you, you use the functions as per normal.

You could also make the wrapper monad have some state, and then batch the operations while making them appear to execute sequentially, or make it appear you are doing pure logic when I/O is happening under the hood.

While you can do monads in dynamic languages, it can be hard to reason about changes to the code without strong compiler support, so typically you see it more often implemented in statically typed languages.

In dynamic languages such as lisp you might be better off writing a small interpreter, and in OO languages there are other patterns that might serve the purpose better.

I still don't know what a monoid is though. Or an applicative.


> I still don't know what a monoid is though

In short, it's a data type with addition defined. So

"a" + "b" = "ab" <-- string and concat is a monoid

1 + 5 = 6 <-- nat and natural number addition is a monoid

[1] + [2] = [1, 2] <-- list and concat is a monoid

*edit* (it also has a zero defined, such as "" or 0 or [])

> Or an applicative

you can think of these as "i'd use a functor here via fmap, except my mapping function takes more than one argument"




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: