I’ve been trying to make music with Haskell for a little while now. One thing about Haskell is that its strict typing forces you to think a lot about how you represent things.
I wanted to support two things in my musical pattern representation, firstly polyphony (more than one sound being triggered at the same time) and secondly recursive structure. In the west we often think of rhythm in quite `flat’ terms – a 2d pattern like this:

Of course that’s a pretty useful techno interface, allows for polyphony, and could be represented in haskell using a straightforward list of lists. However this 2D structure is only really suitable for making music with fixed timed signatures, most notably 4/4.

Time: you're doing it completely wrong
Enter Bernard Bel (pictured right). His BP2 software represents music in a manner inspired by Indian classical music. His 2001 paper Rationalising musical time has all the details and is a great read, formalising a quite beautiful way of thinking about time. As part of that it defines an elegant pattern syntax that allows patterns to be embedded inside patterns of differing time signatures.
Here’s my first attempt at representing analogous structures in Haskell. Straightforwardly, a musical event is either a sound (represented by some string) or some silence:
data Event = Sound String
| Silence
A musical structure is either an event, a cycle of structures, or a polymetry of structures:
data Structure = Atom Event
| Cycle [Structure]
| Polymetry [Structure]
A cycle allows us to sequence structures one after another, and a polymetry allows us to represent several structures occuring over the same period of time. If the structures within a Polymetry have different durations, then they are ‘stretched’ until they are the same length (equal to the lowest common multiple of their lengths). I’ve written something in parsec that parses Bel’s notation into the Structure datatype.
The problem with the above representation is that it gets unwieldy with complex rhythmic structures. The whole point of generative music is being able to make very long patterns out of much shorter rulesets. However with this representation, to find the 10,000th event you’d have to calculate the 9,999 events preceeding it. This becomes a particular problem when modifying these structures as part of a live coded musical improvisation.
So I instead came up with this representation:
data Pattern a = Pattern {at :: Int -> [a], period :: Int}
type SoundPattern = Pattern String
Instead of explicitly representing a recursive structure, I’m now hiding everything inside a function mapping from integers to a list. You pass the function the current position in the pattern (e.g. the current ‘beat’, and get back the list of events at that position. For certain operations you still need to know the period (length) of the repeating pattern, so that’s in the datatype constructor too.
What kind of operations can I do to these patterns? Here’s one that simply shifts events backwards in time:
(<~) :: Pattern a -> Int -> Pattern a
(<~) p steps = Pattern (\n -> at p (n + steps)) (period p)
And in the other direction:
(~>) :: Pattern a -> Int -> Pattern a
(~>) p n = (<~) p (-n)
Here’s a higher order one that applies an operation conditional on the time value (while preserving the period of the original):
when :: (Int -> Bool) -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
when pred f p = Pattern l (period p)
where l n = at (if (pred n) then (f p) else p) n
Making this possible …
when (\n -> n `mod` 8 > 3) (<~ 2) p
… which shifts the pattern back in time two steps, but only affects every other group of 4 steps.
This is probably fairly humdrum stuff, but quite fascinating to me as someone relatively new to both haskell and functional programming. Being able to pile functions on top of functions in this way lets me compose complex patterns out of simple parts, and I only ever have to deal with the simple parts in memory, not the complex patterns. Great! Thanks to the parameterisation of the Pattern datatype, I can also use patterns for different aspects of a rhythm, my recent screencasts [1,2] showing concurrent patterning of samples, vowel formant filtering, sample playback speed and a comb filter.
I’ve also been looking at making the Pattern a Monad (my first ever monad instance, woo!):
instance Monad Pattern where
return x = loop $ [x]
(Pattern l len) >>= f = Pattern l' (lcm len len')
where l' n = at (combine $ map f (l n)) n
(Pattern _ len') = f undefined
Where ‘combine’ is another function not shown that which merges patterns together. The problem I’m having with this is that functions of type a -> Pattern a for use with >>= can’t do that much, not being able to consider any pattern context, and not being able to return a different period depending on the input (otherwise that ‘undefined’ value would bite). This is about the most useful thing I can come up with, which ‘masks’ events every other time measure:
mask :: (a -> Pattern a)
mask x = Pattern (\n -> if n `mod` 2 == 0
then [x]
else []
) 2
Maybe I should be thinking of what I could do with more general functions of type (a -> Pattern b) instead. I guess I’m just getting a better handle on what monads are really for…
Monads aside I guess my Pattern representation would really become unstuck with patterns that have a lot of interdependencies. For example if every event depended on the event preceding it then you’d have to recalculate the whole pattern all the time. Hmm.
Well that was quite an extended haskell wibble. If by some strange chance you’ve read this far I’d love to hear your thoughts and especially advice!