# Functor, Applicative and Monad Pattern

I was reading this interesting post for the hundredth time and I am still trying to understand what's behind the different instances of `Pattern` and especially when it is useful to handle `Monad Pattern`, `Functor Pattern` and `Applicative Pattern`.
Here is what I got so far:

• `Functor Pattern` comes handy when we want to use function from e.g. the standard `Prelude` module but we don't know how to cope with the `Pattern` context. We use `<\$>` and we get a result wrapped in a `Pattern` context that we can use inside Tidal.
E.g. `chop (round <\$> (slow 8 \$ range 1 128 \$ sine))` - thanks @nuelmyr for the pattern
• `Monad Pattern` comes handy when we have a function that returns a `Pattern` context, but it does not accept a value in a context. We use `>>=` and the `Monad Pattern` will apply the function to the `Pattern` and we get a result wrapped in a `Pattern` context.
I think the example from the post is quite explicative:
`fastFromList[False,False,True] >>= \ f -> if not f then run 2 else run 3`

But what about `Applicative Pattern`: what is a pattern of functions (`Pattern (a -> b)`)?

I am very interested in seeing some examples on how you use the different instances of `Pattern` to create your own functions.

Two more points:

• the last example in the post makes use of `>>>=` which I cannot locate in the docs: what does that mean? I tried to evaluate it but it does not work.
• what is a `Pattern (Pattern a)`?
I struggle to understand what a pattern of patterns is, and when it is used.

Using Hoogle, I could find this that references `>>>==`, but I can't make anything of it.

Functor is indeed for running a function over all of the values inside a pattern. `<\$>` is an infix alias for `fmap`, which is conceptually the same as `map`, but works for all functors, not just lists.

``````round <\$> ("1 2.2 3" :: Pattern Double)
``````

Functor is useful for functions with a single input like `round`, but how about `min`, which takes two inputs and returns the smallest one?

Well just giving it one input is legal haskell:

``````min <\$> ("1 2 3" ::Pattern Double)
``````

(I have to put the type signature in there, otherwise it can't tell what kind of number it is, because there's no context for it to infer it from..)
The result is a pattern of functions - `Pattern (Double -> Double)`

That's not too useful though.. How to turn it into a pattern of doubles? Well the Applicative instance give you this:

``````(<*>) :: Applicative f => f (a -> b) -> f a -> f b
``````

Pattern is an Applicative instance, so we can fill that in:

``````(<*>) :: Applicative f => Pattern (a -> b) -> Pattern a -> Pattern b
``````

So that's what it's for, applying a pattern of values to a pattern of functions, giving you a pattern of results..

``````min <\$> ("1 2 3" ::Pattern Double) <*> ("5 0 10")
``````

That's the same as `"1 0 3"`. Useful!
(Tidal also defines `<*` and `*>`, which does the same but takes the structure from the left or right, rather than both.. that's where the `|+` vs `+|` vs `|+|` behaviour comes from. This overloads the definition of <* and *> in the prelude, beware..)

A pattern of patterns is a pattern that has other patterns as values. They crop up a lot internally. For example `fast` didn't used to take a pattern as it's first argument. Fixing this was a case of doing something like this: `newfast timepat pat = innerJoin \$ (\time -> fast time pat) <\$> timepat`

That is, mapping `fast` over the values of `timepat`, ending up with a pattern of patterns.. Then using a join to turn a pattern of patterns into a pattern. (innerJoin means that the structure comes from the patterns inside the patterns..)

`(>>>=)` isn't a standard operator, it's defined in the post.

5 Likes

Aaah so you can do partial application, and this is what gives you: pattern of functions!
It so does make sense!

There is not need to specify the context for `"5 0 10"` because it is already set by `Pattern (Double -> Double)`?

And thanks Alex, this is so amazing and it will keep me busy for a while @yaxu I have two follow up questions.

I checked the type for two similar expressions

``````(\x -> segment 3 \$ irand x) <\$> "3 6 9"
:: (Functor f, Num a, Data.String.IsString (f Int)) =>
f (Pattern a)
``````
``````(\x -> segment 3 \$ irand x) <\$> (irand 6)
:: Num a => Pattern (Pattern a)
``````

I understand the latter but not the former: I see that both are something made of `(Pattern a)`
but I don't understand the `f`. Does that mean a `Functor Pattern`? And why the difference in type?

Moreover, I struggle to understand how differently `innerJoin` and `outerJoin` operate.
Perhaps you have an example to show?

Hi.

Both expressions can be used at type `Pattern (Pattern Int)`.

GHC infers the most general type. All the ingredients are polymorphic, e.g., `irand :: Num a => Int -> Pattern a` creates the `Num a` constraint.

Because of `OverloadedStrings`, we have `"3 6 9" :: IsString a => a`, so it's not even assumed to be `Pattern a`. But since we apply `<\$>`, the `Functor` constraint appears. Etc.

Here is a minimal example for the joins:

``````Prelude Sound.Tidal.Context> outerJoin \$ pure \$ fastcat [pure False, pure True]
(0>1)|False

Prelude Sound.Tidal.Context> innerJoin \$ pure \$ fastcat [pure False, pure True]
(0>½)|False
(½>1)|True
``````

outer pattern is of period one (because `pure`), and at each beat, it produces the same inner pattern, whose structure we see, or don't.

NB: @yaxu I wanted to `outerJoin \$ slowcat [ run 2, run 3 ]` but this gives

``````*** Exception: enumFromTo: not supported for patterns
``````

[EDIT] ghc is right and I was wrong, since I confuse it with `slowcat [ run 2, run 3] :: Pattern Int`. I actually meant

``````innerJoin ( slowcat [ pure \$ run 2, pure \$ run 3] :: Pattern (Pattern Int))
``````

Sorry for the confusion!

NB: It's nice exercise to figure out why the expression `outerJoin \$ slowcat [ run 2, run 3 ]` wasn't rejected by the type checker.

Answer: the numeric literals `2,3` are polymorphic! Let's ask ghc for the type of `3`:

``````outerJoin \$ slowcat [ run 2, run (3 :: _)]

<interactive>:12:40: error:
• Found type wildcard ‘_’ standing for ‘Pattern (Pattern a)’
``````

Also,

``````run :: (Enum a, Num a) => Pattern a -> Pattern a
``````

so here we'd need an `instance Enum (Pattern a)` which does exist but it only implements `succ`, `pred` not `enumFromTo`, which is called by `run`.

1 Like

One thing: what is `pure`?

``````pure :: Applicative f => a -> f a
``````

in Tidal, `pure x` is a pattern that always has value `x` (with period 1). Often, usage of `pure` is invisible, but these are indeed the same:

``````Prelude Sound.Tidal.Context> "0" :: Pattern Int
(0>1)|0
Prelude Sound.Tidal.Context> pure 0 :: Pattern Int
(0>1)|0
``````
1 Like

Sorry for the non-linear edit above. To conclude (for now ...), here's another pair of examples for inner/outerJoin:

``````outerJoin ( fastcat [ pure \$ run 2, pure \$ run 3] :: Pattern (Pattern Int))
(0>½)|0
(½>1)|1

innerJoin ( fastcat [ pure \$ run 2, pure \$ run 3] :: Pattern (Pattern Int))
(0>½)|0
⅓-(½>⅔)|1
(⅔>1)|2

``````