Mininotation: Can {}% be used with <..>?

Hi, I’m new.

Trying to do something like <{a b c}%4 {d e f}%4>
I expected something like this
abca|efde|cabc|defd|bcab|fdef
But instead I get a syntax error, seems like multiple {}% cannot be parsed inside <>

What I’m trying to achieve is exactly the above.

  1. set of patterns
  2. spread those out over a cycle with some tempo, cycling back if needed
  3. some way to “pick” the pattern for each cycle, e.g. something like <0 1>
  4. bonus: the tempo of the “picker” can be set independently, e.g. slow 2 $ <0 1> to get abca|bcab|fdef|defd|bcab|cabc|defd|efde|cabc|abca|efde|fdef

I’m sure tidal has a clean way to do this, but I’m new and struggling.

Thank you

seems like multiple {}% cannot be parsed inside <>

use extra brackets?

ghci> "<[{a b c}%4] [ {d e f}%4]>" :: Pattern String
(0>¼)|"a"
(¼>½)|"b"
(½>¾)|"c"
(¾>1)|"a"

1 Like

Genius, that works.
I ended up getting around it by doing
squeeze (“<0 1>”) [“{a b c}%4”, “{d e f}”%4]
But yours is much cleaner.

Although now I’m running into this other thing, where because of squeeze, I can e.g. simplify
squeeze (“<0 0 1 1>” x as squeeze (fromList $ [0..2] >>= replicate 2) x
Wondering if there’s a cleaner way to do that with mini notation

I think you meant [0..1]

This should do it: squeeze "<0 ! 1 !>"

or: squeeze "<0!2 1!2>"

1 Like

That’s right, but less general, and 0!2 is equally many characters as 0 0.
Less general in the way that if I want <0 0 0 1 1 1 2 2 2 3 3 3> I would still have to type out <0!3 1!3 2!3 3!3>, but fromList $ [0..3] >>= replicate 3) only requires changing two characters. In general, fromList $ [0..n] >>= replicate k) produces < 0!k 1!k .. n!k>
I was hoping someone had a more idiomatic way of producing that pattern.

Here is a better solution that almost avoids repetitive code:

<0 0 0 0 1 1 1 1 2 2 2 2>

slow (3 * 4) $ ply 4 "[0..2]"

I am also curious if a more idiomatic solution exists.

1 Like

That’s nice and tidaly, although now there’s 4 numbers to tweak where the behaviour is really parametrized by only two variables, which is a bit messy.

1 Like

@jwaldmann thanks for this! I actually struggled with this exact same problem and just abandoned the idea altogether :rofl: I mostly use ncat now if I need to string together a bunch of complex patterns

What is ncat?

ncat is (was?) a custom function to help give more control over the sequencing of patterns (pattern happens N times). here is the code if you want to add it to your boot file to try it out.

ncat :: [(Time, Pattern a)] -> Pattern a
ncat = seqPLoop . go 0
  where
    go _     []          = []
    go t_acc ((0, _):ps) = go t_acc ps
    go t_acc ((t, p):ps) = (t_acc, t', p) : go t' ps
      where
        t' = t_acc + t
2 Likes