## Patterns again

Back to patterns in Haskell, an unruly puzzle that’s run through the last few years of my life, trying to work out how I want to represent my music.  Here’s the current state of my types:

```  data Pattern a = Sequence {arc :: Range -> [Event a]}
| Signal {at :: Rational -> [a]}```
```  type Event a = (Range, a)
type Range = (Rational, Rational)```

A Range is a time range, with a start (onset) and duration.  An Event is of some type a, that occurs over a Range.  A Pattern can be instantiated either as a Sequence or Signal.  These are directly equivalent to the distinction between digital and analogue, or discrete and continuous.  A Sequence is a set of discrete events (with start and duration) occurring within a given range, and a Signal is a set of values for a given position in time.  In other words, both are represented as functions from time to values, but Sequence is for representing a set of events which have beginnings and ends, and Range is for a continuously varying set of values.

This is a major improvement on my previous version, simply because the types are significantly simpler, which makes the code significantly easier to work with.  This simplicity is due to the structure of patterns being represented entirely with functional composition, so is closer to my (loose) understanding of functional reactive programming..

The Functor definition is straightforward enough:

`  mapSnd f (x,y) = (x,f y)`
```  instance Functor Pattern where
fmap f (Sequence a) = Sequence \$ fmap (fmap (mapSnd f)) a
fmap f (Signal a) = Signal \$ fmap (fmap f) a```

The Applicative definition allows signals and patterns to be combined in in a fairly reasonable manner too, although I imagine this could be tidied up a fair bit:

```  instance Applicative Pattern where
pure x = Signal \$ const [x]
(Sequence fs) <*> (Sequence xs) =
Sequence \$ \r -> concatMap
(\((o,d),x) -> map
(\(r', f) -> (r', f x))
(
filter
(\((o',d'),_) -> (o' >= o) && (o' < (o+d)))
(fs r)
)
)
(xs r)```
```  (Signal fs) <*> (Signal xs) = Signal \$ \t -> (fs t) <*> (xs t)
(Signal fs) <*> px@(Sequence _) =
Signal \$ \t -> concatMap (\(_, x) -> map (\f -> f x) (fs t)) (at' px t)
(Sequence fs) <*> (Signal xs) =
Sequence \$ \r -> concatMap (\((o,d), f) ->
map (\x -> ((o,d), f x)) (xs o)) (fs r)```

In the Pattern datatype, time values are represented using Rational numbers, where each whole number represents the start of a metrical cycle, i.e. something like a bar.  Therefore, concatenating patterns involves ‘playing’ one cycle from each pattern within every cycle:

```  cat :: [Pattern a] -> Pattern a
cat ps = combine \$ map (squash l) (zip [0..] ps)
where l = length ps```
```  squash :: Int -> (Int, Pattern a) -> Pattern a
squash n (i, p) = Sequence \$ \r -> concatMap doBit (bits r)
where o' = (fromIntegral i)%(fromIntegral n)
d' = 1%(fromIntegral n)
cycle o = (fromIntegral \$ floor o)
subR o = ((cycle o) + o', d')
doBit (o,d) = mapFsts scaleOut \$ maybe [] ((arc p) . scaleIn) (subRange (o,d) (subR o))
scaleIn (o,d) = (o-o',d* (fromIntegral n))
scaleOut (o,d) = ((cycle o)+o'+ ((o-(cycle o))/(fromIntegral n)), d/ (fromIntegral n))```
```  subRange :: Range -> Range -> Maybe Range
subRange (o,d) (o',d') | d'' > 0 = Just (o'', d'')
| otherwise = Nothing
where o'' = max o (o')
d'' = (min (o+d) (o'+d')) - o''```
```  -- chop range into ranges of unit cycles
bits :: Range -> [Range]
bits (_, 0) = []
bits (o, d) = (o,d'):bits (o+d',d-d')
where d' = min ((fromIntegral \$ (floor o) + 1) - o) d```

Well this code could definitely be improved..

If anyone is interested the code is on github, but is not really ready for public consumption yet.  Now I can get back to making music with it though, more on that elsewhere, soon, maybe under a new pseudonym..

## Upcoming events in September 7/8th September 2012, Leeds – Live Interfaces

As my first act as research fellow at ICSRiM, I’m chairing this conference on live interaction in performance technology, two days of papers and performances, including a (free) club night.  The quality of submissions has been fantastic, and we have people coming from 11 different countries outside the UK, can’t wait!

10th September, Slovenia – ICMC 2012

Then I’m off to give a paper on Live notation at the International Computer Music Conference with Hester Reeve.   Looking forward to hanging out in Ljubljana, hope to spend some time in the kiberpapa while I’m there (Sunday-Thursday).

16th September, Germany – Documenta festival

This isn’t 100% confirmed, but the book Speaking Code will be launched at Documenta festival, and while I can’t be there, I will still be live coding there.  More on this once it’s done..