 # Is there some way to get a "negative" whenmod?

`whenmod n m f` will apply f when the cycle number `mod` n > m. Is there some simple way to do the opposite, i.e., apply f when the cycle number `mod` n <= m?

`whenmod n m f` is defined (https://github.com/tidalcycles/Tidal/blob/main/src/Sound/Tidal/UI.hs#L555) via the more general `when`:

`when (\ t -> mod t n >= m) f`

so one could copy this definition, and change the condition, to `when (\ t -> mod t n < m) f`.

Also, I think something like this should hold

``````opposite-whenmod n m f = rotL (n-m) . whenmod n (n-m)  f . rotR (n-m)
``````

but that's perhaps more tricky than useful.

NB: the dot is for function composition, `(f . g . h) x` means `f \$ g \$ h x`

`opposite-whenmod n m f = rotL (n-m) . whenmod n (n-m) f . rotR (n-m)` gives me a type error for the 2nd arg of `whenmod` (it wants Int not Time).

And this is maybe a good opportunity for me to ask my other question. . . My approach to a reverse whenmod was literally to reverse the pattern before and after whenmod. I was thinking along these lines:

`whennotmod n m f = outside n rev . whenmod n (n-m) f . outside n rev`.

But I end up with a similar type error on the the 2nd arg of whenmod (wants Int not Pattern Time). I haven't been to correctly cast that argument, but I assume this should be possible.

Sorry. I only tested with concrete numbers, not variables, so this works:

`````` oppwhenmod83 f = rotL (8-3) . whenmod 8 (8-3) f . rotR (8-3)
``````

With variables:

``````oppwhenmod n m f = rotL (fromIntegral \$ n-m) . whenmod n (n-m) f . rotR (fromIntegral \$ n-m)
``````
1 Like

This works

``````whennotmod n m f = outside (pure \$ fromIntegral n) rev . whenmod n (n-m) f . outside (pure \$ fromIntegral n) rev
``````
1 Like

Thanks - I had tried `fromIntegral`, but it was `pure` that I was missing

I've using this:
`whenmod' n m f = rotL (fromIntegral \$ n-m) . whenmod n (n-m) f . rotR (fromIntegral \$ n-m)`
quite a lot in my code recently.

But when I updated from1.6.1 to 1.7.2, this seems to have broken. I get the following error:

``````• No instance for (Integral (Ratio Integer))
arising from a use of ‘fromIntegral’
``````

Could anyone offer a suggestion? Nothing I've tried has worked.

Now, I have an idea related to this topic.

``````-- "negative" whenmod / apply f when the cycle (< b)
whenmod' :: Pattern Time -> Pattern Time -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
whenmod' a b f pat = innerJoin \$ (\a' b' -> _whenmod' a' b' f pat) <\$> a <*> b
_whenmod' :: Time -> Time -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
_whenmod' a b = whenT (\t -> ((t `mod'` a) < b ))
-- apply f when the cycle between b and c
betweenmod :: Pattern Time -> Pattern Time -> Pattern Time -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
betweenmod a b c f pat = innerJoin \$ (\a' b' c' -> _betweenmod a' b' c' f pat) <\$> a <*> b <*> c
_betweenmod :: Time -> Time -> Time -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
_betweenmod a b c = whenT ( (\t -> ( (t `mod'` a) < b ) && (t `mod'` a) >= c ))
``````

e.g.

``````do
resetCyclesTo (-0.05)
d1 \$
(# s "gtr") .(# legato 1) \$
whenmod 8 6 (const \$ slow 2 \$ arp "up" \$ note "f'maj9'o") \$ -- 6, 7
betweenmod 8 6 4 (const \$ note "[-12,0,4,7,11,19]") \$ -- 4 , 5
whenmod' 8 2 (const \$ fast "<4 8>" \$ note "c'maj9") \$ -- 0, 1
note "0 4 7 11 2 6 <9 11> <14 16>" -- 2 ,3
d2 \$ s "<bd cp sd cp>"
``````
2 Likes