Skip to content

Instantly share code, notes, and snippets.

@zudov
Last active September 15, 2015 06:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zudov/3001e85c9bbf4650905e to your computer and use it in GitHub Desktop.
Save zudov/3001e85c9bbf4650905e to your computer and use it in GitHub Desktop.
MiniSodium v1
module MiniSodium where
import Prelude
import Data.Maybe
import Control.Apply
import Control.Bind
data Stream m a = Stream { sample :: m (Maybe a) }
runStream (Stream s) = s
instance functorStream :: (Functor m) => Functor (Stream m) where
map f (Stream s) = Stream { sample: map f <$> s.sample }
never :: forall m a. (Applicative m) => Stream m a
never = Stream { sample: pure Nothing }
filterS :: forall a m. (Functor m) => (a -> Boolean) -> Stream m a -> Stream m a
filterS pred (Stream s) = Stream { sample: guardMaybe pred <$> s.sample }
where
guardMaybe pred (Just x) | pred x = Just x
guardMaybe _ _ = Nothing
merge :: forall a b c m. (Apply m) => (a -> b -> c) -> Stream m a -> Stream m b -> Stream m c
merge f (Stream sa) (Stream sb) = Stream { sample: lift2 f <$> sa.sample <*> sb.sample }
data Behavior m a = Behavior { sample :: m a }
runBehavior (Behavior b) = b
-- FIXME: Incorrect. When event doesn't occur we need to return the latest value, not an initial one
hold :: forall a m. (Functor m) => a -> m (Maybe a) -> m a
hold a sa = fromMaybe a <$> sa
instance functorBehavior :: (Functor m) => Functor (Behavior m) where
map f (Behavior b) = Behavior { sample: f <$> b.sample }
instance applyBehavior :: (Apply m) => Apply (Behavior m) where
apply (Behavior bf) (Behavior ba) = Behavior { sample: ($) <$> bf.sample
<*> ba.sample }
instance applicativeBehavior :: (Applicative m) => Applicative (Behavior m) where
pure a = Behavior { sample: pure a }
snapshot :: forall a b c m. (Apply m) => (a -> b -> c) -> Stream m a -> Behavior m b -> Stream m c
snapshot f (Stream sa) (Behavior bb) = Stream { sample: sample }
where
sample = lift2 f <$> sa.sample <*> (Just <$> bb.sample)
switchS :: forall a m. (Bind m) => Behavior m (Stream m a) -> Stream m a
switchS (Behavior b) = Stream { sample: join (_.sample <<< runStream <$> b.sample) }
switchC :: forall a m. (Bind m) => Behavior m (Behavior m a) -> Behavior m a
switchC (Behavior b) = Behavior { sample: join (_.sample <<< runBehavior <$> b.sample) }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment