Live data from Hacker News

List is a monad

alexyorke.github.io

151–160 of 187 posts

Re: List is a monad

#151

Earlier quoted context omitted.

now write a single function that performs from x in xs select fn(x) and define a signature for it where `xs` and `fn` are the only input arguments, so that it accepts both `listB` and `taskB` without a compilation error.

Right, ‘some type that has a Select(Func ) method available’ is not a thing you can express in C# generic constraints. But I don’t need a function that does that, the language has syntax for it - I can just do that wherever I need it.

Yes, but you can’t write something that’s generic over “things that support Select” because that’s not expressible via the type system.

So you can’t write a function, then get a version that works on lists, then a version that works on tasks, then a version that works on nullables, then get a version that works on parsers. One if the big secrets on monads is that Haskell users don’t spend very much time thinking about them, while people without monads have to think about them all the time.

Re: List is a monad

#153

The way I think of it, monads are a solution to Callback Hell, where you've fallen in love with lambdas, but now you have a nightmarish mess of lambdas in lambdas and lambdas calling lambdas. The monadic functions allow you to create "for comprehensions" aka "do comprehensions" but really, they look like a classic for-each loop. They secretly call the monadic map/flatMap/filter functions. for x in list doThings(x) Th…

After reading your comment, I've made it my mission to understand it. Although I have no idea what you're talking about, you make it sound intriguing.

What parent describes is pretty simple: That's just how the compiler transforms some code.

Do-notation in Haskell, or for-comprehensions in Scala are just syntax sugar for nested calls to `flatMap`, `filter`, and `map`.

I think this here shows it nicely:

https://www.baeldung.com/scala/for-comprehension#for-compreh...

In Scala you can add the needed methods to any type and than they will "magically" work in for-comprehensions. In Haskell you need to implement a Monad instance which than does the same trick.

The concrete implementations of these methods need to obey to some algebraic laws for the data structure which defines them to be called a monad. But that's pretty much it.

In my opinion all that Haskell in most "monad tutorials" just blurs an in principle very simple concept.

The in practice relevant part is that a monad can be seen as an interface for a wrapper type with a constructor that wraps some value (whether a flat value, some collection, or even functions, makes no difference), does not expose an accessor to this wrapped value, and has a `flatMap` method defined. It also inherits a `map` method, coming from an interface called "Functor". The thing is also an instance of an "Applicative", which is an interface coming with a `combine` method which takes another object of the same type as itself and returns a combination of again the same type (classical example: string concatenation can be a `combine` implementation if we'd say that `String` implements the `Applicative` interface).

Re: List is a monad

#154
post #86

Earlier quoted context omitted.

To get a minimal idea, you can think about a monad as of a parametrized class: M . Its functioning follows "monad laws" that allow you to do certain things with it, and with the value(s) of T wrapped my it. In particular, you can always "map" the values: M ::map(f: (T1 -> T2)): M List ([1, 2, 3]).map(x => toString(x)) == List (["1", "2", "3"]) You can always flatten the nested structure: M >::flatten(): M // [["a", "…

> immediately transforms into Minor quibble, "can only be resolved as". The runtime absolutely holds Promise >'s.

Splitting hairs even further: the .then() returns a resolved value of the inner Promise, not the inner Promise itself, when the outer Promise resolves, so not "immediately" indeed. That's where the flattening occurs, AFAICT.

Re: List is a monad

#155

I will die with the crushing embarrassment of not being able describe what a monad is, despite being a so-called (and apparently fake) programmer since the age of 10.

There's nothing embarrassing about not knowing the details of a sub-field you're not deeply involved in.

Like, why would you embarrassed about not understanding the details of MPLS networking if you're not a network engineer who works with MPLS?

Re: List is a monad

#156

The article sort of danced around what I think is the most natural way List is a "recipe": it's the bounded nondeterminism monad (a `List ` is a nondeterministic result; one could implement `List -> T` by selecting an answer uniformly at random from the finite multiset).

I really like my lists to be deterministic.

Seriously, I've read things about lists and nondeterminism a few times in this thread, and I can't help but wonder if "you guys" (functional programming nerds, maybe?) use the word "nondeterministic" different than the rest of the world?

If not, I'd love a good explanation about what makes lists non-deterministic, and why we would want that, and why they seem to be perfectly deterministic in imperative programming languages.

Re: List is a monad

#157
post #109

Earlier quoted context omitted.

Every monad is also an applicative and liftA2 does/is the same thing as liftM2. The only reason they both exist was due to Monad being popularized in Haskell earlier than Applicative and thus not having it as a superclass until the Functor-Applicative-Monad Proposal in Haskell 2014. It was obviously correct, but a major breaking change that also got pork barreled a bit and so took a while to land.

Yes you're absolutely right. I had a bit of a brain fart moment here. If they were Applicative operations then you would not be able to use `liftM2`, not the other way around.

This is my fear when I think about doing actual in a team using a functional language. That there's an imbalance in understanding between participants in a team making all discussions about problem x into the pattern matchning problem y. Like "is this liftM2 or liftA2?"

I've only had a couple of months of experience working with scala before the team switched to Java. The reasons were many but one of them was that the external consultant that was most knowledgeable in "thinking with functions" was kind of a dick. Making onboarding into a horror show of "go look up yt video x before I can talk about this functionality" with a condescending tone. So within a month he was let go and then no one in the remaining team really had the courage to keep debe it further. Some thought that they maybe could maintain the current functionality but the solution was only like half complete. (in the consultant mind it was complete because it was so generic you only needed to add a couple of lines in the right place to implement each coming feature)

That said, I would love to work in a hardcore Haskell project with a real team, one with a couple of other "regular" coders that just help each other out when solving the actual problems at hand.

Re: List is a monad

#158
post #63
post #38

Earlier quoted context omitted.

What can a Haskell monad do that a Python class cannot? 99% of all monads I've seen only facilitate local state manipulation.

It's not about what a monad can do, it's about a property of the language: referential transparency. Haskell has referential transparency, Python doesn't. That's a technical condition but here's a simple consequence: effect typing. In Haskell you can know what possible effects an operation has from its type. Here's an example from my effect system, Bluefin: foo :: _ => Exception String e1 -> State Int e2 -> Eff es Bo…

Those annotations create a compile-time enforced typological relationship between the input and output values of the function. Python doesn't have mandatory type-checking so it can't do that. But parent wasn't referring to type-checking. They claimed monads have expressive power unavailable in other languages.

Re: List is a monad

#159

Earlier quoted context omitted.

I'm sorry, I'm not sure I understand entirely what you are trying to express by Func , List -> List That said, in C#, you can write: List listA; Task taskA; Func func; List listB = from i in listA select func(i); Task taskB = from t in taskA select func(t); And if it can resolve a method on List called 'Select' that takes a Func that returns a List , and a method on Task called 'Select' that takes a Func that returns…

now write a single function that performs from x in xs select fn(x) and define a signature for it where `xs` and `fn` are the only input arguments, so that it accepts both `listB` and `taskB` without a compilation error.

In C++:

    template class Container, class T, invocable Fn>
    Container > map(Container container, Fn fn) {
      return to(transform(container,  fn));
    }
(Although idiomatically you wouldn't write the code this way).

Whether that counts as HK types, I'll leave it to others to discuss.

Re: List is a monad

#160

So I come at this from a math background but I’ve always found these explanations to be overly complex. In the parlance of C++, I think of a monad as a template class T with the following properties: 1. For any class X, there is a canonical method F: X -> T 2. For any class X, there is a canonical method G: T > -> T . 3. For classes X and Y, and any method f: X -> Y, there is a corresponding method “T ”: T -> T . ———…

A monad would not be a template class in C++, it would a concept (more or less the c++ equivalent of an Haskell type class).
Post reply on HN