Live data from Hacker News

Functor, Applicative, and Monad

typeslogicscats.gitlab.io

11–20 of 125 posts

Re: Functor, Applicative, and Monad

#11

An important realization that I had was that monads/functors/applicatives aren't patterns in the sense of design patterns. You don't solve a singular problem with a monad. With something like a strategy pattern you have a concrete problem: how do I select different potential algorithms? Monads don't have a specific problem that they solve. Any attempt to motivate monads in such a manner falls flat because the problem…

> And therefore, it's perfectly acceptable to say "I know how monads work with Maybe and List, but not Reader" Because fundamentally, how a Reader implements bind is in no way related to how Maybe or List implement bind.

If this is indeed true, what is the point of learning these "patterns"? From a mechanical understanding of the signature of bind and unit, you'd arrive at more sophisticated signatures, say filterM, but an understanding of what it does will still need an understanding of the specific implementation of the Monad instance it is being applied on. That sounds like a leaky abstraction. If so, why bother?

Re: Functor, Applicative, and Monad

#12
post #10

It's just mind boggling how universal these concepts are and how they show up in surprising ways. As a recent example, I've been learning the basics of composing music in Haskell with Euterpea[1] and wanted to make a function which played several notes over a list of octaves to make chords. It turns out the applicative operator was exactly the function I need to do this! It would be hard to go into the details in jus…

I have never heard of Euterpea, nor have I seen the rest of your code, but I suggest you refactor your slightly convoluted code like this: notePlayer notes octs dur = musicSeq $ notes octs pure dur Coincidentally, this might be a testament of the power of parametric polymorphism and equational reasoning.

My favorite part about Haskell is how you can know literally nothing about the domain and make meaningful changes to programs regardless thanks to local reasoning.

That's really one power of functor/applicative/monad - if you understand their interfaces, you can work with new unfamiliar types that have these instances without much effort at all.

Re: Functor, Applicative, and Monad

#13

An important realization that I had was that monads/functors/applicatives aren't patterns in the sense of design patterns. You don't solve a singular problem with a monad. With something like a strategy pattern you have a concrete problem: how do I select different potential algorithms? Monads don't have a specific problem that they solve. Any attempt to motivate monads in such a manner falls flat because the problem…

> And therefore, it's perfectly acceptable to say "I know how monads work with Maybe and List, but not Reader" Because fundamentally, how a Reader implements bind is in no way related to how Maybe or List implement bind. If this is indeed true, what is the point of learning these "patterns"? From a mechanical understanding of the signature of bind and unit, you'd arrive at more sophisticated signatures, say filterM,…

To my understanding, although the behaviors of filterM, etc. differ depending on the monad instance, as long as the monad instances follow the laws, those functions like filterM have predictable behavior. It's a consequence of "theorems for free" / parametricity.

Re: Functor, Applicative, and Monad

#15
post #14

I should learn to read Haskell one of these days. Not today though.

The majority of my tutorial actually uses OCaml, though. :P

I like OCaml because it strikes a balance between imperative and functional programming. Maybe learning OCaml would be easier than learning Haskell?

(Plus, OCaml has neat features like polymorphic variants and a powerful module system!)

Re: Functor, Applicative, and Monad

#16

Even better http://adit.io/posts/2013-04-17-functors,_applicatives,_and_...

I am the author of this submission. I have strong opinions about functor and monad tutorials, and here are my thoughts: Back when I didn't understand what a monad was, I would read a bunch of tutorials and get confused by the analogies and examples. For example, I would get confused by comparisons to "boxes," or I would think that Maybe was the definition of a monad, or that IO was the definition of a monad. The info…

As Doug Crockford once said "In addition to it begin useful, it is also cursed and the curse of the monad is that once you get the epiphany, once you understand - "oh that's what it is" - you lose the ability to explain it to anybody." [1]

I think someone who is a beginner or just want to use Functor / Applicative / Monad without mastering underlying Category Theory, boxed model seems good enough. However, if you are creating own monads, then of-course we need to understand monadic laws. Every programming language has monad of some sort e.g. Optional in Java. To use optional chaining, I may not need to know all details but only how `flatMap` works. Maybe I am wrong too :).

[1] https://www.i-programmer.info/news/167-javascript/5207-crock...

Re: Functor, Applicative, and Monad

#17
I don't think this article is very useful. It doesn't adequately provide an introduction to OCaml code (or adequately explain what a given code snipped is doing) and yet frequently defers to just code to explain a concept. It's an unrealistic expectation to expect an unfamiliar reader to simultaneously infer what a particular code snippet is doing then also go a level deeper and understand the concept that is trying to be presented.

This article is most readable to those who already understand OCaml code, and if you can already read OCaml code you already understand these concepts.

Re: Functor, Applicative, and Monad

#18
Nice explanation of monads!

My two cents: personally, I would've started with the fact that a monad is exactly the stringing together of functions (a -> m b), and the similarity between monoids, monads, strings / lists and functions under composition. You mentioned that

• (a -> [b]) is the type of non-deterministic computations

• (a -> Maybe b) is the type of fallible computations

• (a -> IO b) is the type of effectful computations

• (a -> (s, b)) is the type of computations with state s

• that the Monad instance merely specifies how to compose them

• all such composable constructs can be expressed as a monad

• do notation and list comprehensions automatically work across all of them

and, in my opinion, these are all much more powerful motivation than beginning with a comparison to functors.

Re: Functor, Applicative, and Monad

#19

An important realization that I had was that monads/functors/applicatives aren't patterns in the sense of design patterns. You don't solve a singular problem with a monad. With something like a strategy pattern you have a concrete problem: how do I select different potential algorithms? Monads don't have a specific problem that they solve. Any attempt to motivate monads in such a manner falls flat because the problem…

> And therefore, it's perfectly acceptable to say "I know how monads work with Maybe and List, but not Reader" Because fundamentally, how a Reader implements bind is in no way related to how Maybe or List implement bind. If this is indeed true, what is the point of learning these "patterns"? From a mechanical understanding of the signature of bind and unit, you'd arrive at more sophisticated signatures, say filterM,…

The point is that Monad, Applicative and Functor are well defined interfaces with laws (properties) you can count on.

They are in fact much better, more precisely defined than classic design patterns.

And in expressive programming languages (that support higher kinded types or that at least let you encode such types) you can also describe generic code that works over any applicative or monadic type.

Having reusable functions that work just as well on lists, maybe/option, reader, io / promise or what have you means these type classes do a very good job at abstracting over data types. These are the purest forms of abstraction.

And you can get syntactic sugar from the language as well. For example "for comprehensions" in Python work via the iterator/enumerable protocol, but that's super limiting. Haskell's "do notation" or Scala's "for comprehensions" work on any monad instead, being much more powerful and reusable.

Unfortunately it takes an expressive language to understand and work with these abstractions comfortably. You won't grok monads in Go or Java.

Re: Functor, Applicative, and Monad

#20
post #10

It's just mind boggling how universal these concepts are and how they show up in surprising ways. As a recent example, I've been learning the basics of composing music in Haskell with Euterpea[1] and wanted to make a function which played several notes over a list of octaves to make chords. It turns out the applicative operator was exactly the function I need to do this! It would be hard to go into the details in jus…

I have never heard of Euterpea, nor have I seen the rest of your code, but I suggest you refactor your slightly convoluted code like this: notePlayer notes octs dur = musicSeq $ notes octs pure dur Coincidentally, this might be a testament of the power of parametric polymorphism and equational reasoning.

Amazing, thanks! It always amazes me how natural Haskell is for some people. Some seem to see the simplest solution with so little effort while I still struggle with almost embarrassingly simple things. I wish I would have picked up Haskell as my first language, instead my mind was poisoned by C...
Post reply on HN