Apfelmus
apfelmus.nfshost.com · Personal blog · on HN since 2009
Apfelmus writes Haskell tutorials on lazy evaluation, finger trees, monoids, and the operational monad.
What HN saysCommenters call the lazy evaluation series a substantive, unusually well-crafted tutorial, and HN links it for explaining Haskell concepts clearly.
22HN people shared it
12linked it in comments
11stories submitted
135story points
3 years agolast shared
2009people per year2026
Most-shared posts
- 1Fast implementations of data structures using monoids and finger trees7 people · 9 points · first shared 2012 · discussion on HN
- 2Quicksearch2 people · first shared 2010
- 3Blog2 people · first shared 2012
- 4Operational monad2 people · first shared 2013
- 5How Does Lazy Evaluation Work in Haskell? (2014)1 people · 72 points · first shared 2020 · 4 comments on HN
- 6Fun with Morse Code1 people · 23 points · first shared 2009 · 2 comments on HN
- 7Excellent video explaining GADTs in Haskell1 people · 22 points · first shared 2010 · 3 comments on HN
- 8The best of explanation of Finger Trees (data structure) I have seen1 people · 3 points · first shared 2009 · 2 comments on HN
- 9Haskell FRP – Release of reactive-banana 1.01 people · 2 points · first shared 2015 · discussion on HN
- 10HyperHaskell is a graphical Haskell interpreter (REPL)1 people · 2 points · first shared 2018 · discussion on HN
- 11Forklift – a pattern for performing monadic actions in a worker thread (2012)1 people · 1 points · first shared 2015 · discussion on HN
- 12Reasoning about space leaks with space invariants (2013)1 people · 1 points · first shared 2023 · discussion on HN
- 1303 frp dynamic event switching 0 71 people · first shared 2013
- 14Lazy eval1 people · first shared 2020
- 1529 frp three principles bidirectional gui1 people · first shared 2021
What HN people wrote when they linked it
zenhack · 2018-02-16
First, going straight to "How do I understand Monads?" is not a good idea. I remeber when this article showed up on the web, and I remember wishing it had been written before I started learning Haskell:
https://byorgey.wordpress.com/2009/01/12/abstraction-intuition-and-the…
If you want to understand monads, start hacking and watch for patterns.
> But, just to be super honest -- and possibly completely wrong -- the terminology is really off-putting. At a glance it just feels super complex, academic and completely divorced from practical coding. I get vibes of enterprise java class hierarchies looking at this stuff.
Yeah, and here's my take on why it looks like that:
First, the terminology is all borrowed from mathematics, hence the academic tone. People can debate on the merits of this; I think it makes more sense when you're making tools for folks who are already familiar with the usual notation, but e.g. if you're not dealing with people who are already accustomed to the way physisicts talk about things, "p" is probably not the best variable name for momentum, traditional as it may be.
The authors of that document seem to have gone even farther in that direction than the Haskell folks -- Setoid? really? It's just fing equals! even Haskell calls it Eq. At least they kept Ord.
Also, the design looks to be basically transliterated from Haskell. There's been no attempt to adapt it to either javascript's strengths or its weaknesses. For example:
…
tikhonj · 2013-01-22
This is where "event switching" comes in. Unfortunately, I have not used Elm or FlapJax, so I am not sure if the terminology is the same there.
Traditional FRP has two main concepts: behaviors, which are values that can change continually, and stream of events. Scanning over this blog post, these ideas correspond roughly to Properties and EventStreams respectively in Bacon.js.
Event switching is just having an event stream that itself contains behaviors. There's a great blog post[1] about this using Reactive Banana and Haskell.
[1]: http://apfelmus.nfshost.com/blog/2012/09/03-frp-dynamic-event-switchin…
Most of the post is fairly Haskell-specific, talking about the type system, but the basic idea should be applicable here as well.
The running example is a bar tab. You want to be able to create new entries in the tab, which are just text entries that give you a price. So you would create something like
entries :: Event [Behavior Price]
That is, you have a stream of events that contains behaviors corresponding to each text entry widget you've added. This makes calculating things like the sum of all the widgets relatively easy.
I'm not sure how other libraries support this dynamic event switching though. My understanding is that it is somewhat tricky to implement efficiently.
benreesman · 2022-07-31
Drop me a line at [email protected] and I'll let you know when we can open-source some of it.
None of it is really all that magical btw, so you should take a whack at it yourself!
One thing that wouldn't have occurred to me that one of the Haskell geniuses I work with identified to use is the notion of a "free"/"operational" monad: https://apfelmus.nfshost.com/articles/operational-monad.html.
gbrown_ · 2020-03-07
The first in a series of articles, a list of which can be found here https://apfelmus.nfshost.com/articles/lazy-eval.html
dang · 2014-11-22
Hmm. HN likes substantive articles and dislikes sketchy tactics. Those two almost never conflict. When they do, though, we tend to favor the substantive article, which this one clearly is. It's an elementary tutorial, yes, but an unusually well-crafted one, and had it appeared on the author's website (http://apfelmus.nfshost.com/blog.html), there'd be no question.
Perhaps the positive reinforcement of seeing what actually works to get on the HN front page—solid content—will combine with earlier negative reinforcement—prior sketchy tactics have gotten this site penalized—to induce a change in behavior. I know that sounds unicorny, but the last time something like this came up on HN, a different site actually cleaned up its ways. Maybe lightning will strike twice.
oggy · 2013-03-12
Kiselyov et al have an interesting paper on logic programming in Haskell [1]. They introduce a backtracking monad transformer with fair disjunctions, and negation-as-failure and pruning operations. And the implementation is based on continuation, so it's more efficient than reification-based approaches such as e.g. Apfelmus's operational monad [2]
[1]: http://www.cs.rutgers.edu/~ccshan/logicprog/LogicT-icfp2005.pdf
[2]: http://apfelmus.nfshost.com/articles/operational-monad.html
nandemo · 2012-01-17
1. Install reactive-banana and read its docs and Apfelmus' intro (i).
2. Write a simple, 80s-style game using it.
3. Write a short tutorial explaining it.
4. ???
5. Profit.
(i) http://apfelmus.nfshost.com/blog.html#functional-reactive-programming-…
kaiwetzel · 2011-06-05
Interesting blog post about how this could be done in Haskell using a suitable mergesort (or quicksort): http://apfelmus.nfshost.com/articles/quicksearch.html (pointed out in a similar discussion some time ago). Having used Haskell in university only, articles like this really make me want to revisit the language.
(Algorithms aside, the full sort of 10M numbers, apparently using an underlying C implementation, looks stunishingly slow: Given at most 240M comparisons for merge-sorting the array, taking 10s would mean at throughput only 24M items per sec, bad memory access pattern at play maybe?)
ithkuil · 2010-08-02
I found this article referencing the O(n) complexity for the 'head . sort'
http://apfelmus.nfshost.com/articles/quicksearch.html
As far as I can understand from the blog and and the cited mailing lists, it works but it requires
a carefully coded sorting method, otherwise O(n log n) as expected.
mananaysiempre · 2021-06-07
Because so far noöne has figured out the set of extensibility points needed for a language-agnostic one that doesn’t result in horrible bloat and sprawling API surfaces. The original language-agnostic IDE—Emacs—is probably the simplest, and it’s still quite complex. Acme[2] is interesting, but Spartan when it comes to actual IDE-ish features, and its UI always rubbed me the wrong way.
I feel this is somewhat related to the fact that noöne has figured out how to do extensible widget toolkits or scene graphs either. (Yes, Electron does in fact solve an actual problem, if in a profoundly unsatisfying way.) Actually, just a text input box that could handle the complexities of the world’s writing systems (RTL, complex font shaping, arbitrary input methods, autocorrect, all that with at least one cursor or selection) and was capable of supporting the facts vs rumors approach from FRP[1] would be a significant advancement re toolkits. As for scene graphs, I don’t actually know of any viable general approaches to assembling an interface out of independent parts (that doesn’t work by presupposing a large substrate of features in the host “shell” and providing a separate extension point for each of shortcut, menu item, toolbar button, sidebar, dialog, ...).
Actually, now that I’ve written all of that out, it seems that another way to put my second point is that the language-agnostic IDE problem is a proper superset of the composable GUIs problem, and nobody knows how to solve that…
chas · 2014-01-18
I'm happy to see finger trees got mentioned. Finger trees[0] are extremely useful and general data structure that can be used to implement persistent sequences, priority queues, search trees and priority search queues. (Haskell's Data.Sequence[1] uses specialized 2-3 finger trees internally) They can form the basis of all sorts of interesting custom structures by supplying the appropriate monoid[3], but this does make them harder to approach if you are not familiar with the abstractions.
[3] A monoid is any structure that has members that can combine associatively. In addition, it must have an element that can combine with any other element and result in the other element. Some examples: (strings, string concatenation, the empty string); (integers, addition, 0); (natural numbers, max, 0); (booleans, and, True); (functions, composition, the identity function). The functional pearl[2] that describes the design of Haskell's diagrams library[4] goes into much more detail if you are interested in their application to programming.
[0] http://apfelmus.nfshost.com/articles/monoid-fingertree.html
[1] http://hackage.haskell.org/package/containers-0.5.4.0/docs/Data-Sequen…
[2] http://www.cis.upenn.edu/~byorgey/pub/monoid-pearl.pdf
[4] http://projects.haskell.org/diagrams/
jerf · 2013-01-11
If you want to work in an environment where a lot of people are thinking like this routinely, instead of a few lone voices in a vast sea of otherwise uninterested people, the Haskell community is doing a lot of work in this area, and able to move much faster since it's so much easier in Haskell than C++ templates (which isn't really a criticism of C++ templates, a lot of their capabilities are accidental rather than intended). This is why the Haskell community talks so much about monoids and applicatives and semigroups and a variety of other interesting structures in that area (and no, I did not forget to say monad, that structure is actually uninteresting here because it is too powerful). I believe the Fortress language is also doing some work here.
A sample of the interesting sort of algorithm work that you can do when you think this way: http://apfelmus.nfshost.com/articles/monoid-fingertree.html
Edit: See also the Typeclassopedia: http://www.haskell.org/haskellwiki/Typeclassopedia And if you're really interested and want to take it hardcore, Edward Kmett's video on his lens library walks through how you can derive it with this sort of logic: http://youtu.be/cefnmjtAolY?hd=1