Whenmod 8.5 6.5 possible?

I'm hoping to find a way to input partial cycles to control when whenmod takes effect.

Is there a way to do this? I'm hoping I'm just missing the right syntax.

Thank you

1 Like

Looking into the Tidal codebase, I see that whenmod is implemented as follows:

whenmod :: Int -> Int -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
whenmod a b = Sound.Tidal.Core.when (\t -> (t `mod` a) >= b )

You can see that it uses the mod function to determine when to trigger the function. If, as I believe it is, it's the basic Haskell function from the Prelude, its type signature is mod :: Integral a => a -> a -> a, which means that, unfortunately, it only takes integers (or numbers behaving as such) as arguments.

(I'm realizing at that point that I could have just checked the time signature of whenmod, which is a very explicit whenmod :: Int -> Int -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a, but what I wrote certainly has pedagogical merits.)

What you could do is redefine whenmod so that it doesn't use mod anymore, but it's extended version mod' (which you will probably have to import).
You Tidal script would then become:

import Data.Fixed(mod')

whenmod :: Int -> Int -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
whenmod a b = Sound.Tidal.Core.when (\t -> (t `mod'` a) >= b )

-- your music here
2 Likes

Oh wow! Will try it out asap, thank you!

Pardon me for being such an annoying n00b but I evaluated the above lines in Atom, first line as single line eval and the two below together and Atom was giving no errors.

But if I try to use a whenmod 4.5 3.5 in tidal after the above it gives me this error:

t> 
    • No instance for (Fractional Int) arising from the literal ‘4.5’
    • In the first argument of ‘whenmod’, namely ‘4.5’
      In the expression:
        whenmod 4.5 3.5 (const $ n "[~ -12 ~ ]*6" # s "midi")
      In the second argument of ‘($)’, namely
        ‘whenmod 4.5 3.5 (const $ n "[~ -12 ~ ]*6" # s "midi") $ s "hh*16"’

Apparently I'm not doing it right.

Ah, I see what I did wrong, the type signature of whenmod still asks for Ints. This is what you get when you post code without testing it.
I'll get back to you when I find a fix.

Superb, thank you!

Ok, I think I've got it, the problem was that the conditional function fed to Sound.Tidal.Core.when takes an Int as an argument, which has to be explicitly converted into something that mod' can take as an argument. Also, it was missing some type constraints.
Here is a version that should work (this time I have tested it):

whenmod :: (Ord b, Real b, Num b) => b -> b -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
whenmod a b = Sound.Tidal.Core.when (\t -> (((fromIntegral t) `mod'` a) >= b ))
2 Likes

This is so sweeeeeeet!! Thank you so very much for your knowledge and help with the higher level Haskell, much appreciated!

1 Like

Great, a pull request would be welcome!

Done! Sorry for the delay, been busy recently.

2 Likes