Moved to Innards as it's a bit involved..
I'd generalise the type so it works with any number, as in Tidal notes aren't integers but floats.
inversion :: Num a => Int -> [a] -> [a]
inversion _ [] = []
inversion n xs = drop n xs ++ [ x + 12 | x <- take n xs ]
Then I'd get it to with with lists of Tidal events rather than values:
eventInversion :: Num a => Int -> [Event a] -> [Event a]
eventInversion _ [] = []
eventInversion n xs = drop n xs ++ (fmap (fmap (+12)) $ take n xs )
I used fmap to work in the values inside events, and for brevity used fmap on the list too instead of the list comprehension.
Then I made this function that allows you to group any co-occuring events and work on them together:
withFriends :: ([Event a] -> [Event b]) -> Pattern a -> Pattern b
withFriends f pat = withEvents munge pat
where munge es = concatMap (f) (groupBy (\a b -> whole a == whole b) $ sortOn whole es)
Then bring it together:
invert :: Num b => Int -> Pattern b -> Pattern b
invert = withFriends . eventInversion
d1 $ n (invert 2 "c'maj e'min'4") $ sound "superpiano"