A software designer website

Polysemy: An introduction

Gautier DI FOLCO November 23, 2022 [Haskell] #haskell #polysemy #design #effects systems

I used to teach functional programming using Haskell in an engineering.

I was starting my course by defining functional programming being defined by three interdependent components:

I was emphasizing Haskell's precise type system, and all went well until they encountered IO.

Haskell provides a lot of tools to create a fine grained design for pure computations (with (G)ADTs, types synonyms, etc.), but when it comes to I/O, we have one generic type.

While it may simplify my course, it's not helpful for my production-level products.

A way to mitigate that is to use effects systems, which are design to have small, well-defined effects, grouped in typed.

A widespread implementation of this mechanism is the mtl, but it has a number of issues (and here).

Since September 2020 I'm using Polysemy (see my feedback one year later).

This log is the first one of a long series going through Polysemy.

I'll use Polysemy with GHC 9.2.5, I'll drop the code here.

Let's start with a simple example:

import Polysemy
import Polysemy.Trace

displayFile :: FilePath -> Sem '[Trace, Embed IO] Int
displayFile path = do
  trace $ "Displaying " <> path
  content <- embed $ readFile path
  embed $ putStr content
  return $ length content

We define a function displayFile which produce a Sem expression which:

Step by step we do the following things:

See the full the code here.