<$> and overloading

Is <$> something functor-related?
I've been reading this for the third time and I have been trying to find real applications when writing Tidal code.

These things puzzle me too, after some Googling I found out that <$> is the infix operator version of fmap, which is indeed Functor-related. I think it's used here to apply the round function to every element of whatever the range function produces. Thanks for posting your question, I never knew how to convert a float pattern to an integer pattern :thinking:

For instance:

round 1.5 -- gives 2
round [1.5,2.1] -- gives an error
round <$> [1.5,2.1] -- gives [2,2]
round $ range 2 32 sine -- gives an error "Exception: round: not supported for patterns"
round <$> range 2 32 sine -- gives ~0>1~|17

Maybe someone else like @yaxu can give a more insightful answer to this one :wink:

I've got http://learnyouahaskell.com/ on my todo list, I think it'll be very useful to demystify some of these Haskell's mechanics.

2 Likes

(We're straying off topic a bit, so I'll move this stuff to 'innards')

Yes <$> is fmap, which is basically a map that works for all functors, not just lists.

Tidal is a bit different from Haskell, firstly due to the mininotation which is a language parsed by haskell, rather than being haskell, and secondly due to some overloading of numbers and strings, which is useful can be confusing when trying to apply Haskell knowledge to it.. So here's a couple of general pointers..

Things like "bd sn" in sound "bd sn" look like strings, but are patterns. Basically there's a function called parseBP_E (parse bol-processor notation, and catch exceptions) that's silently called when Tidal finds a string when it was expecting a pattern. This is why e.g. sound ("bd " ++ "sn") doesn't work.. sound (parseBP_E $ "bd " ++ "sn") should.

Likewise 3 in squiz 3 looks like a number, but is a pattern of numbers, in this case a pattern of a 3, triggering every cycle. This works because patterns of numbers are defined to be part of the number class. That is, patterns of numbers are numbers.

However while this works:

round (3.4 :: Double)

and this works:

(3.4 :: Pattern Double) + (4.5 :: Pattern Double)

.. but this doesn't:

round (3.4 :: Pattern Double)

Unfortunately I think it's not possible to define a general enough round for patterns.

With round <$> (3.4 :: Pattern Double) it does work, because then you're working with numbers inside patterns, instead of treating that patterns of numbers as being numbers..

7 Likes

I feel like some kind of operator glossary would have been really helpful when I started out. I found it really confusing when I started learning Tidal which operators belonged to Haskell and which to Tidal (e.g., that $ is Haskell and # is Tidal) - and both are really heavy on operators. Functions can be googled, but operators are rarely search engine friendly. Having some place that points you to where you need to go to learn more would be a useful jumping off point for people starting out.

2 Likes

Hoogle works pretty well for searching operators and Haskell-related stuff.

3 Likes