Articles on Haskell
Last updated: 2023/02/02
Top deep-dives on Haskell
Software projects usually start out fairly simple, but can then get very complicated, very quickly. Most of the time it feels like you're trading doing something fast for technical debt down the line. In this case study article, Eric Normand presents a real-life-esque situation that involves continuously changing specifications for a back end that is meant to validate and store user info. Eric demonstrates how you can use Haskell's type system to take a more dynamic approach towards writing flexible and clean code.
Joachim Breitner talks about how "CPS-conversion and defunctionalization can help you to come up with a constant-stack algorithm".
OOP vs functional programming, the battle of the century! Honestly, I think debating about which is better is like debating what's better for building a house, a hammer or a saw. But I digress. In this article Getty Ritter, as the title suggests, covers what implementing an object in a functional programming language like Haskell would look like. Getty also highlights the advantages and disadvantages of using such an implementation.
Sydney Kerckhove illuminates the potential problems when handling money in code and proposes potential solutions. Be aware that the library he recommends is his own. Information is good nonetheless though.
Micah Cantor explains monads through the lens of first class functions as data.
Traversal Systems, as defined by the author of this article Chris Penner, allow "you [to] dive deeply into a piece of data and may allow you to fetch, query, and edit the structure as you go while maintaining references to other pieces of the structure to influence your work". Basically it's a system for navigating and manipulating data structures where nesting is frequently used (JSON, HTML, CSS, etc). In this article, Chris builds one in Haskell to handle JSON, using optics and monads to query and update objects.
Sandy Maguire uses Haskell to tackle the issue of performant parallel code being too complex to comfortably use in most applications. "No wonder we’re all stuck pretending our computer machines are single threaded behemoths from the 1960s"--ring a bell?
Yesterday, concepts like laziness seemed so far away, but now it looks as though they're here to stay, oh, I believe in laziness; which is generally defined in programming as loading or computing resources only at the time when they are needed. Gary Verhaegen's article focuses on how laziness in Clojure can handle side effects (whereas Haskell requires purity), with examples of Clojure programs being reimplemented in Haskell.
grep is the unexpected poster child for functional programming. Why? Because it "It hides the details of resource manipulation", "It consumes its input lazily", and "It cleans up its resources". In this deep dive, Patrick Thomson uses grep as a model program upon which to base a Haskell lazy I/O streaming implementation.
The article explains the concept of zippers in functional programming using the development of a computer game based on the Greek myth of Theseus and the Minotaur as an example. It's pretty entertaining.
- Theseus is tasked with creating the game, and he decides to represent the labyrinth as a tree
- Zippers are "a purely functional way to augment tree-like data structures like lists or binary trees with a single focus or finger that points to a subtree inside the data structure and allows constant time updates and lookups at the spot it points to"
- Zippers of different data types can literally be derived (calculus, remember?)
Cheng Shao "introduces libffi, the challenges to make it work with WebAssembly, demonstrates [their] implementation, and also explains how it’s used by GHC runtime".
Gabriella Gonzalez highlights why and when Applicatives should implement Semigroup and Monoid.
Erik Engheim explains how to do I/O in a pure functional language using Algebraic Effects.
- In a functional programming language, I/O is typically done using algebraic effects
- This allows for the ability to "bubble up" the call stack until you decide to handle them, similar to how methods in Java need to be declared as throwing exceptions if they call one or more other methods throwing exceptions
- "I/O code can look complex primarily because you are unaccustomed to Unison style error handling", but once you learn it, it becomes a fairly obvious solution
A zipper is a pointer or handle to a particular node in a tree or list structure. In this article, Sandy Maguire explores a paper by Conor McBride that goes into depth about "what happens to a zipper when we don’t require the elements on either side to have the same type".
Working in software, you've probably dabbled with the idea of making your own programming language. What would it take? Abhinav Sarkar has written a series on implementing his own language called Co, in Haskell. In this article, Abhinav details the process of adding dynamic and strong typing, primitives, arithemtic operations, conditionals, and functions.
A space leak is when something in a program takes up more memory than expected (as a very broad definition). Theses are an issue, because they can eventually lead to your program crashing. In this article, Tom Ellis demonstrates how the bang operator can be used to prevent such leaks, highlights issues with the solution, and provides an alternative.
Yorick Sijsling and Joris Burgers have written a series of articles on how to do efficient parallel processing in Haskell.
- "This post explains how we parallelized our system without incurring any significant overhead costs, allowing us to linearly speed-up our workloads with the number of cores available"
- Streaming data is necessary to reduce the amount of memory used during processing
- Making streams function in parallel is the key to the problem
Matt Parsons presents his package for "robust exception reporting and diagnosing facilities" in Haskell, while giving insight into how exceptions work.