I was surprised by this behaviour of (>>=)
:
this should be a stream of "note 0", at 1/2, 3/2, 5/2, etc?
d1 $ pure 0 >>= \ _ ->
( (1/2) ~> (s "superpiano" + note 0 ))
But it's not, events are at 0, 1/2, 1, 3/2, 2, 5/2, ...
By the Monad law pure x >>= f = f x
, it should be equivalent to
d1 $ ( (1/2) ~> (s "superpiano" + note 0 ))
which gives the expected result.
test case without audio:
ghci> pure () >>= \ _ -> rotR (1/2) ( pure () )
(0>½)|()
(½>1)|()
ghci> rotR (1/2) ( pure () )
-1½-(0>½)|()
(½>1)-1½|()
ghci> tidal_version
"1.9.5"
it's not primarily about monads - my application was an offbeat chord in a reggae, where the pattern before (>>=)
gives the base note.
Ah, now I see - I want the monadic bind via innerJoin
, while current (>>=)
uses unwrap
.
ghci> (\ p f -> unwrap (fmap f p)) ( pure () ) ( \ _ -> rotR (1/2) ( pure () ) )
(0>½)|()
(½>1)|()
ghci> (\ p f -> innerJoin (fmap f p)) ( pure () ) ( \ _ -> rotR (1/2) ( pure () ) )
-1½-(0>½)|()
(½>1)-1½|()
ghci> rotR (1/2) ( pure () )
-1½-(0>½)|()
(½>1)-1½|()
just by grepping and counting, it seems to me that innerJoin
is used much more often than unwrap. Perhaps the observation in my question is the reason?
NB - previous discussion (of monadic bind and laws) Instance Monad Pattern should use squeezeJoin instead of unwrap? ... and the current observation is " should use innerJoin"?
[EDIT] here is another example for innerJoin $ fmap ..
(that is, >>=
) Using dynamic values inside within or whenT - #2 by yaxu