## Euclidean rhythm generator in Haskell

So, Haskell! After a few days of astonished dabbling, the Euclidean Rhythm exercise had to be repeated. Again, this is beginner level code and we rely entirely on type inference.

The function breakdown is a little different this time. Two helper functions:

• `ezip`: a hybrid of zip and outer join, takes two lists of different lengths and concatenates their elements pairwise;
• `efold`: repeatedly applies the tail end of the sequence under construction to the head, using `ezip`, until either there are 3 or fewer subpatterns or the pattern is cyclic.

The entire solution:

```euclidean k n = concat . efold \$
(replicate k ) ++ (replicate (n - k) )

ezip x [] = x
ezip [] x = x
ezip (x:xs) (y:ys) = (x ++ y) : ezip xs ys

efold xs
| length xs <= 3 = xs
| a == [] = xs
| otherwise = efold \$ ezip a b
where (a, b) = partition (/= last xs) xs
```

And that's it! Notice how concise yet readable this is compared to an already terse Clojure version.

Similar to the Clojure example, it is not immediately obvious why `a == []` is a terminal case. Empty `a` really means this: `partition` was unable to find different elements because they are identical -- the pattern is cyclic. A less efficient but more explicit way to write this would have been with a `allSame` function:

```euclidean' k n = concat . efold' \$
(replicate k ) ++ (replicate (n - k) )

ezip' (x, []) = x
ezip' ([], x) = x
ezip' ((x:xs), (y:ys)) = (x ++ y) : ezip' (xs, ys)

allSame [] = True
allSame [x] = True
allSame (x:y:xs) = (x == y) && allSame (y:xs)

efold' xs
| length xs <= 3 = xs
| allSame xs = xs
| otherwise = efold' . ezip' \$ partition (/= last xs) xs
```

And, a test:

```*Play> euclidean 3 5
[1,0,1,0,1]
*Play> euclidean 3 8
[1,0,0,1,0,0,1,0]
```