Tidal's monad(s), or: unwrap vs. squeezeJoin

Hi. I wrote a short text on the applicative and monadic structure of Tidal patterns. It compares unwrap with squeezeJoin.
https://www.imn.htwk-leipzig.de/~waldmann/etc/untutorial/tc/monad/ . Comments welcome. - J.W.

Wow looking forward to reading this, just commenting on very strange synchronicity as we were just discussing this very topic on the chat ! https://chat.toplap.org/channel/tidal?msg=pJx6hYkkvk3E82KyQ

Just reading through… Firstly I’d say that this hasn’t been discussed very much. I’m a self-taught haskell programmer, and haven’t had enough interaction with the Haskell community. When I have I’ve learned a lot! E.g. from this post, although Tidal’s representation has changed a lot since then https://ryani.livejournal.com/19471.html

I didn’t really understand the section “More Operations on Patterns” - <*, *> and <*> are about ‘wholes’ rather than values. They control what happens if you combine two events of different sizes. The new event always ends up as the intersection of the two events. But tidal also remembers the original ‘whole’ of which an event is a part (or fragment) of. With <*>, the whole is an intersection of the two wholes. With <* the whole is taken from the left, with *> it’s taken from the right. This is something I’ve worked out relatively recently…

editing this as I read through…

This is interesting:

run 8 # irand 2

# will combine the two patterns but throw away all the values from the one on the left, only taking its structure. irand 2 is continuous and doesn’t have structure. I think you’re using run to turn a pattern into with a continuously varying value into one with discrete events? The idiomatic way to do this would be segment 8 $ irand 2

In general I haven’t fully thought through what should happen when combining continuous and discrete events… So converting everything to discrete events is a good idea!

Anyway, thanks @jwaldmann for clarifying all this. clarissaAdjoint on the chat was also looking at unwrap, innerJoin, outerJoin and squeezeJoin, and found that the latter is the only one that currently seems to meet the monad laws, so perhaps that should become the ‘default’ one.

There’s a lot of use of the applicative instance, but in practice I don’t know of anyone actually using the Tidal monad instance, perhaps there is some useful UI to discover in this…

Hi Alex. Thanks for replying. Here’s another coincidence: my friend Heinrich told me (just yesterday) that he was investigating Functorial structure for music and gave a presentation at FARM 2019, see https://github.com/HeinrichApfelmus/cnoidal .

Great!
Just to correct myself - I misunderstood, unwrap and squeezeJoin meet the laws but inner and outer join do not. I wonder if there are other possible monadic joins?