module Reactive.Banana.MIDI.Utility where
import qualified Reactive.Banana.Bunch.Combinators as RB
import qualified Control.Monad.Trans.State as MS
import Control.Monad (liftM, liftM2, )
import Prelude hiding (sequence, )
partition ::
(a -> Bool) -> RB.Event a -> (RB.Event a, RB.Event a)
partition p =
(\x ->
(fmap snd $ RB.filterE fst x,
fmap snd $ RB.filterE (not . fst) x)) .
fmap (\a -> (p a, a))
mapMaybe ::
(a -> Maybe b) -> RB.Event a -> RB.Event b
mapMaybe f = RB.filterJust . fmap f
partitionMaybe ::
(a -> Maybe b) -> RB.Event a -> (RB.Event b, RB.Event a)
partitionMaybe f =
(\x ->
(mapMaybe fst x,
mapMaybe (\(mb,a) -> maybe (Just a) (const Nothing) mb) x)) .
fmap (\a -> (f a, a))
bypass ::
(a -> Maybe b) ->
(RB.Event a -> RB.Event c) ->
(RB.Event b -> RB.Event c) ->
RB.Event a -> RB.Event c
bypass p fa fb evs =
let (eb,ea) = partitionMaybe p evs
in RB.union (fb eb) (fa ea)
bypassM ::
(Monad m) =>
(a -> Maybe b) ->
(RB.Event a -> m (RB.Event c)) ->
(RB.Event b -> m (RB.Event c)) ->
RB.Event a -> m (RB.Event c)
bypassM p fa fb evs =
let (eb,ea) = partitionMaybe p evs
in liftM2 RB.union (fb eb) (fa ea)
traverse ::
(RB.MonadMoment m) =>
s -> (a -> MS.State s b) -> RB.Event a ->
m (RB.Event b, RB.Behavior s)
traverse s f = sequence s . fmap f
sequence ::
(RB.MonadMoment m) =>
s -> RB.Event (MS.State s a) ->
m (RB.Event a, RB.Behavior s)
sequence s =
RB.mapAccum s . fmap MS.runState
mapAdjacent ::
(RB.MonadMoment m) => (a -> a -> b) -> a -> RB.Event a -> m (RB.Event b)
mapAdjacent f a0 =
liftM fst . RB.mapAccum a0 . fmap (\new old -> (f old new, new))