Euterpea Reading Notes I


I’m starting to read The Haskell School of Music, (HSM) by Paul Hudak and Donya Quick. These notes show how to set up Euterpea, the Haskell package used in HSM. We also give a few examples of how to construct and play music using Euterpea. The examples, taken from Euterpea2-Examples/NoteLevel/ BlueLambda.lhs, are by Donya Quick. Quick’s website points to many good references on Euterpea and algorithmic music and also features some of her compositions.

Another reference for setting things up is Taro Kuriyama’s GitHub repo

It would be very good if someone could verify the procedure on a “clean” machine to ensure that it is correct, complete, and reproducible. While the instructions below are by no means the only way to install and configure Euterpea, they do work.

There are a number of steps and challenges:

  1. Installing GHC
  2. Installing Euterpea
  3. Installing a synthesizer
  4. Configuring the synthesizer
  5. Testing

1. Installing GHC

I used the installer at It gives you ghc, cabal, and stack.

This part went well.

2. Installing Euterpea

This is tricky. The best resource is the download and installation page of It is important to use the right version of GHC in installing Euterpea. If you do not, installation will fail. It is recommended to use cabal for installation, but I prefer stack. It is possible it do this with the correct instructions. Here is what to do.

Set up a new project: stack new euterpea

If you do cd euterpea, you get this:

$ tree
├── Setup.hs
├── app
│   └── Main.hs
├── eutx.cabal
├── package.yaml
├── src
│   └── Lib.hs
├── stack.yaml
└── test
   └── Spec.hs

Getting the correct version of GCH

Look at stack.yaml and find the line which looks something like resolver: lts-16.13. The lts stands for long-time support. This line determines the version of GHC. The version numbers for lts and ghc are not the same.

According to the download and installation page, you must use a GHC version in the range 8.2 through 8.6.5. Change lts-*.* to lts-12.26. This will ensure that GHC 8.4.4 is used. If you now run stack ghci, GHCi will come up, reporting version 8.4.4.

Setting the dependencies (stack.yaml)

Still in stack.yaml, define the extra dependencies:

- Euterpea-2.0.6
- PortMidi-
- arrows-
- Stream-
- lazysmallcheck-0.6

Setting the dependencies (package.yaml)

Modify package.yaml so that the dependencies section looks like this:

- base >= 4.7 && < 5
- Euterpea

Run stack ghci again, and try this:

*Main Lib> import Euterpea
*Main Lib Euterpea> note (1/4) (A, 4)
Prim (Note (1 % 4) (A,4))

If you get as far as seeing Prim (Note (1 % 4) (A,4)), you know that Euterpea is properly installed.

3. Installing a synthesizer

Running the Euterpea code playDev 0 $ c 4 qn sends a MIDI command to the configured synthesizer on channel 0, producing a quarter-note C in octave 4. The synthesizer receives MIDI commands and turns it into sound. Our tasks are to install a synthesizer and configure the communication between it and Euterpea.

The synthesizer

Donya Quick’s MIDI page, last modified Sep 13, 2019, has lots of good information. There are a number of options, among which are

  1. SimpleSynth
  2. fluidsynth (use brew install fluidsynth)
  3. Sforzando

I am now using (2) fluidsynth. See Taro Kuriyama’s GitHub repo for more information on this program.

4. Configuring the synthesizer

Follow the directions on Donya Quick’s page. section 2. Below is an extract of her directions.

  1. Find Audio MIDI Studio in /Applications and double-click on it.

  2. If you are lucky, you will get 2-3 windows that open up and one of them will be called “MIDI Studio.” If you don’t see that window, go up to the top left of the screen and go to Audio MIDI Setup > Preferences and make sure the box called “MIDI Window” is ticked.

  3. Once you have MIDI Studio open, double-click on “IAC Driver.”

  4. There should be a list called “Ports.” If this is empty, you don’t have any ports set up. To add a new port, click the “+” button. This port will now always be there (potentially unless you upgrade your OS version – then you might need to go through these steps again).

  5. You can manage the ports you have as you need new ones or if you want to remove some later. Typically it’s good to have at least 2 ports at any given time. You can give your ports meaningful names if you want by double-clicking the name of the port.

NOTE: The above may not be necessary. Some synthesizers open virtual ports by themselves. I have not been able to test this, so please let me know if the above is always necessary.

5. Testing

Once you have your synthesizer(s) installed, you should test to see if Euterpea can see them. Note that you must start your synthesizer before you start Euterpea.

Here is what I got:

*Main Lib Euterpea> devices

Input devices:
  InputDeviceID 0    IAC Driver Bus 1

Output devices:
  OutputDeviceID 1    IAC Driver Bus 1
  OutputDeviceID 2    FluidSynth virtual port (48276)
  OutputDeviceID 3    sforzando

In this case, Euterpea sees three devices. I used the third to play a note:

*Main Lib Euterpea> playDev 2 $ c 4 qn

If you hear a quarter-note C, you know that Euterpea works for you. Time to celebrate!

Now for some music

There is a page of resources and things to try when starting out, e.g:

playDev 2 $ line [c 4 qn, c 4 qn, g 4 qn, g 4 qn, a 4 qn, a 4 qn, g 4 hn]

If you have configured things the right way (I haven’t), you can use play instead of playDev 2.

Test again

Let’s make sure that we can get back into Euterpea after we have quit:

-- $ stack ghci
-- > import Euterpea
-- > devices -- check to see which device to use
-- Input devices:
--   InputDeviceID 0    IAC Driver Bus 1
-- Output devices:
--   OutputDeviceID 1    IAC Driver Bus 1
--   OutputDeviceID 2    FluidSynth virtual port (48276)
-- Ah, yes, I'll use device 2
-- > playDev 2 line [c 4 qn, c 4 qn, g 4 qn, g 4 qn, a 4 qn, a 4 qn, g 4 hn]

Something more elaborate

The examples below are taken from Euterpea2-Examples/NoteLevel/BlueLambda.lhs by Donya Quick.

> x1 = c 4 en :+: g 4 en :+: c 5 en :+: g 5 en
> x2 = x1 :+: transpose 3 x1
> x3 = x2 :+: x2 :+: invert x2 :+: retro x2
> x4 = forever x3 :=: forever (tempo (2/3) x3)
> playDev 2 x4

As explained the first chapter of Hudak and Quick’s book, The Haskell School of Music, playing foo :+: bar is to play foo, then bar, while foo :=: bar is to play foo and bar simultaneously.

The version below introduces a half-note offset:

> x4' = forever x3 :=: (rest hn :+: forever (tempo (2/3) x3))
> playDev 2 x4'


Euterpea, Tutorials and Talks