diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/ChangeLog.md
@@ -0,0 +1,3 @@
+# Changelog for try-evt
+
+## Unreleased changes
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Author name here (c) 2022
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Author name here nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,20 @@
+# dyna - FRP library
+
+The `dyna` is functional reactive programming (FRP) library for Haskell.
+It implements classical FRP and probvides easy to use 
+interface to write call-back heavy interactive applications.
+
+## Tutorial
+
+* [Introduction](https://github.com/anton-k/dyna-frp/blob/main/dyna/tutorial/00-intro.md)
+* [Event streams](https://github.com/anton-k/dyna-frp/blob/main/dyna/tutorial/01-event-streams.md)
+* [Console game example](https://github.com/anton-k/dyna-frp/blob/main/dyna/tutorial/03-event-game-example.md)
+* [Dynamic values](https://github.com/anton-k/dyna-frp/blob/main/dyna/tutorial/04-dynamics.md)
+* [Backbone FRP monad](https://github.com/anton-k/dyna-frp/blob/main/dyna/tutorial/05-backbone-monad.md)
+* [Control flow. Sharing event streams and recursion](https://github.com/anton-k/dyna-frp/blob/main/dyna/tutorial/06-control-flow.md)
+* [How to make bindings to imperative libraries](https://github.com/anton-k/dyna-frp/blob/main/dyna/tutorial/07-make-bindings.md)
+* [Parsers of event streams](https://github.com/anton-k/dyna-frp/blob/main/dyna/tutorial/08-parser.md)
+* [Conclusion](https://github.com/anton-k/dyna-frp/blob/main/dyna/tutorial/09-conclusion.md)
+* [Quick reference](https://github.com/anton-k/dyna-frp/blob/main/dyna/tutorial/101-reference.md)
+* [Resources](https://github.com/anton-k/dyna-frp/blob/main/dyna/tutorial/102-resuorces.md)
+
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/dyna.cabal b/dyna.cabal
new file mode 100644
--- /dev/null
+++ b/dyna.cabal
@@ -0,0 +1,73 @@
+cabal-version: 1.12
+
+name:           dyna
+version:        0.1.0.0
+synopsis:       Minimal FRP library
+description:    Defines minimal FRP library (classical FRP)
+homepage:       https://github.com/anton-k/dyna-frp#readme
+bug-reports:    https://github.com/anton-k/dyna-frp/issues
+author:         Anton Kholomiov
+maintainer:     anton.kholomiov@gmail.com
+copyright:      2022 Anton Kholomiov
+category:       FRP
+license:        BSD3
+license-file:   LICENSE
+build-type:     Simple
+extra-source-files:
+    README.md
+    ChangeLog.md
+
+source-repository head
+  type: git
+  location: https://github.com/anton-k/dyna-frp/dyna
+
+library
+  exposed-modules:
+      Dyna
+      Dyna.Ref
+  hs-source-dirs:
+      src
+  build-depends:
+      base >=4.7 && <5
+    , async
+    , Boolean
+    , mtl
+    , stm
+    , random
+    , unagi-chan
+    , unbounded-delays
+    , lifted-base
+    , lifted-async
+    , monad-control
+    , MonadRandom
+    , vector
+    , vector-space
+    , temporal-media
+    , time
+  default-language: Haskell2010
+  default-extensions:
+    DeriveFunctor
+    RankNTypes
+    LambdaCase
+    FlexibleContexts
+    FlexibleInstances
+    ExistentialQuantification
+    TypeApplications
+    TypeFamilies
+    TupleSections
+    GeneralizedNewtypeDeriving
+    UndecidableInstances
+    ImportQualifiedPost
+
+test-suite dyna-test
+  type: exitcode-stdio-1.0
+  main-is: Spec.hs
+  other-modules:
+      Paths_dyna
+  hs-source-dirs:
+      test
+  ghc-options: -threaded -rtsopts -with-rtsopts=-N
+  build-depends:
+      base >=4.7 && <5
+    , dyna
+  default-language: Haskell2010
diff --git a/src/Dyna.hs b/src/Dyna.hs
new file mode 100644
--- /dev/null
+++ b/src/Dyna.hs
@@ -0,0 +1,1532 @@
+-- | Dyna is functional reactive programming library.
+-- It describes event streams that are based on callbacks.
+-- The event stream can produce something useful with callback that it consumes.
+-- Also we have continous signals called @Dyn@ (short for dynamic).
+-- The Dyn is sort of observance process of an event stream. For any
+-- event that happen on event stream we remember that value and produce it
+-- at any time until the next event will happen.
+--
+-- # Events
+--
+-- The event stream is just callback consumer funtion:
+--
+-- > newtype Evt m a = Evt {
+-- >   runEvt :: (a -> m ()) -> m ()
+-- > }
+--
+-- So it tells us: If you give me some callback @(a -> m ())@ I will apply it to the event
+-- when event will occur. But when it will occur we don't know until we run the event.
+-- All events happen at the same time. Every event triggers a callback.
+-- This has some special nuance to it. That can differ from other FRP libraries.
+-- For example monoidal append of two event streams:
+--
+--  > evtA <> evtB
+--
+-- In many FRP libraries we choose which element will happen or should we also append the events
+-- if they happen "at the same time". For this library we spawn two concurrent processes
+-- on background so if two events will happen at the same time callback will be called twice.
+--
+-- # Dynamics
+--
+-- The assumption is that dynamic is a process that evolves in time.
+-- And as a human beings we can only ask for current values while process happens.
+-- So we assemble the dynamics with combinators an after that we can run it's process:
+--
+-- > ref <-runDyn dynamicValue
+--
+-- It produces reference to the process which we can use to sample the current value in real time:
+--
+-- > readDyn ref
+-- >  10
+-- > readDyn ref  -- 5 seconds later
+-- >  10
+-- > readDyn ref  -- 5 seconds later
+-- >  3
+--
+-- This reminds us of the notion of present moment. Take for example a weather temperature.
+-- We can claim to build a model of weather and have an assumption of which value will happen tomorrow
+-- but the exact value for it we can only measure at the moment when it will actually happen.
+--
+-- So the library is based on simple assumptions:
+--
+-- * Event stream is a callback processor
+--
+-- * Event stream happen at the same time as concurrent process
+--
+-- * Dynamic is a process and we can only query the current value for it
+--
+-- * Dynamics are based on event streams. The dynamic is an observation of some underlying event streams.
+--    We just remember the last event and keep producing it until the next one wil arrive.
+module Dyna(
+  -- * Pipe
+  (|>),
+  -- * Class
+  Frp(..),
+  -- * Events
+  Evt(..),
+  once,
+  never,
+  -- * Dynamics
+  Dyn(..),
+  constDyn,
+  runDyn,
+  DynRef(..),
+  readDyn,
+  cancelDyn,
+
+  -- * Control
+  newEvt,
+  newDyn,
+  withDyn,
+
+  -- * API
+  -- * Event API
+  scan,
+  scanMay,
+  mapMay,
+  accum,
+  accumB,
+  accumMay,
+  filters,
+  filterJust,
+  whens,
+  splits,
+  lefts,
+  rights,
+  iterates,
+  withIterates,
+
+  fix1,
+  fix2,
+  fix3,
+  fix4,
+  switch,
+  joins,
+
+  delay,
+  delayFork,
+
+  sums,
+  sumD,
+  integrate,
+  integrate2,
+  products,
+  count,
+  withCount,
+  appends,
+  foldMaps,
+  takes,
+  drops,
+  takesWhile,
+  dropsWhile,
+  cycles,
+  listAt,
+  toToggle,
+
+  forevers,
+  races,
+  forks,
+  -- * Render streams
+  heads,
+  prints,
+  putStrLns,
+  folds,
+  foldls,
+  foldls',
+  foldrs,
+  foldrs',
+  Parser,
+  runParser,
+  takeP,
+  cycleP,
+  headP,
+  maybeP,
+  -- * Event/Dynamic interaction
+  hold,
+  unhold,
+  scanD,
+  scanMayD,
+  switchD,
+  switchDyn,
+  apply,
+  applyMay,
+  snap,
+  attach,
+  attachWith,
+  attachWithMay,
+  (<@>),
+  (<@),
+  -- * Effectful API
+  FunctorM(..),
+  foreach,
+  posteach,
+  iterates',
+  scan',
+  scanMay',
+  accum',
+  accumMay',
+  filters',
+  mapMay',
+  apply',
+  applyMay',
+  -- * Utilities
+
+  -- **  Channels (interaction with the world)
+  mchanEvt,
+  tchanEvt,
+  uchanEvt,
+  UChan,
+  newTriggerEvt,
+  -- ** IO
+  getLines,
+
+  -- ** Clock
+  clock,
+  pulse,
+  ticks,
+  timer,
+  timerD,
+  -- ** Random
+  toRandom,
+  toRandomR,
+  withRandom,
+  withRandomR,
+  oneOf,
+  withOneOf,
+  freqOf,
+  withFreqOf,
+  randSkip,
+  randSkipBy,
+
+  -- * Re-exports
+  liftA2,
+  liftA3,
+  BasisArity(..),
+  module X,
+) where
+
+import Prelude hiding ((<*))
+import Data.IORef
+import Control.Applicative (liftA2, liftA3)
+import Control.Monad
+import Control.Monad.IO.Class
+import System.Environment
+import Data.Functor
+import Data.Bifunctor
+import Data.Function
+import Data.Maybe (fromJust)
+import Data.Vector qualified as V
+import Data.AdditiveGroup as X
+import Data.AffineSpace as X
+import Data.Basis
+import Data.Cross as X
+import Data.VectorSpace as X
+import Data.String
+import Control.Concurrent.Lifted
+import Control.Concurrent.Thread.Delay qualified as D
+import Control.Concurrent.Async.Lifted
+import Control.Concurrent.STM
+import Control.Concurrent.STM.TVar
+import Control.Concurrent.STM.TChan
+import Control.Concurrent.Chan.Unagi (InChan)
+import Control.Concurrent.Chan.Unagi qualified as U
+import Control.Concurrent.Chan qualified as M
+
+import Control.Monad.Trans.Control
+import Dyna.Ref
+import Data.Time
+import System.Random (Random, newStdGen, randomR, random)
+import Control.Exception.Lifted
+import Control.Monad.Random.Class qualified as R
+import Temporal.Class as X
+
+import Data.Boolean
+
+infixl 4 <@>
+infixl 4 <@
+infixl 0  |>
+
+{-# inline (|>) #-}
+-- | Pipe operator. We often write processors of event streams
+-- It makes it convenient write them from first to the last:
+--
+-- > evt = proc1 |> proc2 |> ... |> procN
+--
+-- Instead of reversed order with @($)@:
+--
+-- > evt = procN $ ... $ proc2 $ proc1
+(|>) :: a -> (a -> b) -> b
+a |> f = f a
+
+
+class (IsRef (Ref m), MonadBaseControl IO m, MonadIO m) => Frp m where
+  type Ref m :: * -> *
+
+instance Frp IO where
+  type Ref IO = TVar
+
+-- | Dynamics are step-wise constant effectful functions
+-- each step transition is driven by underlying stream of events.
+--
+-- Meaning of the Dyn is a process that evolves in time.
+-- We can start the process by running @runDyn@. It produces a reference to the
+-- process that runs in background.
+--
+-- > runDyn :: Frp m => Dyn m a -> DynRef m a
+--
+-- When reference is initialized we can query current  value of it:
+--
+-- > readDyn :: DynRef m a -> m a
+--
+-- When we are done with observations we should shut down the background process with:
+--
+-- > cancelDyn :: DynRef m a -> m ()
+--
+-- It kills the background process and triggers the release function of underlying event stream.
+data Dyn m a
+  = forall s . Dyn
+      { dyn'get     :: s -> m a   -- ^ get the value from internal state
+      , dyn'evt     :: Evt m s    -- ^ stream of state updates
+      , dyn'init    :: m s        -- ^ initial state
+      , dyn'release :: m ()       -- ^ release resources for dynamic
+      }
+    -- ^ event based dynamic
+  | ConstDyn a
+    -- ^ Constant value
+
+-- | Reference to running dynamic process by which we can query values (@readDyn@).
+-- Also note that we no longer need the reference we should release the resources
+-- by calling @cancelDyn@.
+data DynRef m a
+  = forall s . DynRef (s -> m a) (Ref m s) ThreadId (m ())
+  | ConstRef a
+
+-- | Runs dynamic within the scope of the function.
+-- It provides a callback with dyn getter as argument and after
+-- callback finishes it shutdowns the dyn process.
+withDyn :: Frp m => Dyn m a -> (m a -> m b) -> m b
+withDyn dyn f = bracket (runDyn dyn) cancelDyn (\ref -> f (readDyn ref))
+
+-- | Dyn that is constructed from effectful callback.
+constDyn :: Frp m => m a -> Dyn m a
+constDyn act = Dyn (const act) never (pure ()) (pure ())
+
+instance Functor m => Functor (Dyn m) where
+  fmap f (ConstDyn a)                = ConstDyn (f a)
+  fmap f (Dyn extract evt s release) = Dyn (fmap f . extract) evt s release
+
+instance Frp m => Applicative (Dyn m) where
+  pure a = ConstDyn a
+  (ConstDyn f) <*> (ConstDyn a) = ConstDyn (f a)
+  (ConstDyn f) <*> (Dyn aget aevt as release) = Dyn (\s -> f <$> aget s) aevt as release
+  (Dyn fget fevt fs release) <*> (ConstDyn a) = Dyn (\s -> ($ a) <$> fget s) fevt fs release
+  (Dyn fget fevt fs releaseF) <*> (Dyn aget aevt as releaseA) =
+    Dyn (\(f, a) -> (fget f) <*> (aget a)) evt (liftA2 (,) fs as) (releaseF >> releaseA)
+    where
+      evt = Evt $ \go -> do
+        tv <- proxyNewRef evt =<< liftA2 (,) fs as
+        void $ fork $ runEvt joint $ \case
+          Left  s -> do
+            liftIO $ modifyRef tv (first $ const s)
+            go =<< liftIO (readRef tv)
+          Right s -> do
+            liftIO $ modifyRef tv (second $ const s)
+            go =<< liftIO (readRef tv)
+
+      joint = fmap Left fevt <> fmap Right aevt
+
+-- | Event stream. The meaning of an event is a callback consumer function.
+-- If we give callback to it it will do something useful based on it.
+--
+-- The main function is runEvt:
+--
+-- > runEvt :: Evt m a -> (a -> m ()) -> m ()
+-- > runEvt events callback = ...
+--
+-- Let's look at simple examples of the event streams:
+--
+-- Event that never produce anything:
+--
+-- > never = Evt {
+-- >    runEvt _ = pure ()
+-- >  }
+--
+-- So it just ignores the callback and returns right away.
+--
+-- Event that happens only once:
+--
+-- > once :: m a -> Evt m a
+-- > once get = Evt {
+-- >     runEvt go = go =<< get
+-- >  }
+--
+-- It just gets the value right away and applies callback to it.
+-- We can try it out in the interpreter:
+--
+-- > putStrLns $ fmap ("Your message: " <> ) $ once getLine
+--
+-- We have useful functions to print out the events: @putStrLns@ and @prints@.
+--
+-- Also we have event streams that happen periodically:
+--
+-- > prints $ clock 1  -- prints time every second
+--
+-- ## Duplication of the events.
+--
+-- Note that event streams are functions that do side-effects within some monad.
+-- We use them as values but it means that two values with the same event stream definition
+-- can produce different results. For example:
+--
+-- > a = toRandomR (0, 10) $ clock 1
+-- > b = a
+--
+-- Note that a and b will each have their own copy of underlying random event stream.
+-- So if you use it in the code don't expect values to be the same.
+--
+-- But if we want them to be the same we can copy event from it's definition with function:
+--
+-- > newEvt :: Evt m a -> m (Evt m a)
+--
+-- It starts the underying event stream process n background and sends all events
+-- to the result by channel. With nice property of when we shut down the result event the
+-- background process also shuts down.
+--
+-- > a <- newEvt toRandomR (0, 10) $ clock 1
+-- > b = a
+--
+-- In this example event streams @a@ and @b@ will have the same events during execution.
+newtype Evt m a = Evt { runEvt :: (a -> m ()) -> m () }
+
+-- | Event that happens only once and happens right away.
+once :: Frp m => m a -> Evt m a
+once ask = Evt $ \go -> go =<< ask
+
+-- | Event that never happens. Callback function is ignored.
+never :: Frp m => Evt m a
+never = Evt (const $ pure ())
+
+-- | Runs the argument event stream as background process
+-- and produces event stream that is fed with events over channel (unagi-channel package).
+-- When result event stream shuts down the background process also shuts down.
+newEvt :: Frp m => Evt m a -> m (Evt m a)
+newEvt evt = do
+  ch <- liftIO $ U.newChan
+  tid <- fork $ runEvt evt $ liftIO . U.writeChan (fst ch)
+  pure $ uchanEvtFinally tid (pure $ fst ch)
+
+uchanEvtFinally :: (Frp m) => ThreadId -> m (InChan a) -> Evt m a
+uchanEvtFinally tid mchan = Evt $ \go -> do
+  chan <- liftIO . U.dupChan =<< mchan
+  loop chan go `finally` (killThread tid)
+  where
+    loop chan go = do
+      a <- liftIO $ U.readChan chan
+      go a
+      loop chan go
+
+-- | Runs the dynamic process in background and returns dynamic
+-- that just samples the background proces with @readDyn@.
+newDyn :: Frp m => Dyn m a -> m (Dyn m a)
+newDyn dyn = do
+  ref <- runDyn dyn
+  pure $ Dyn readDyn never (pure ref) (cancelDyn ref)
+
+instance Functor (Evt m) where
+  fmap f (Evt evt) = Evt $ \proc -> evt (proc . f)
+
+instance Frp m => Semigroup (Evt m a) where
+  (<>) (Evt a) (Evt b) = Evt $ \proc ->
+    concurrently_ (a proc) (b proc)
+
+-- | Shutdown the remaining event if one of the events close up early.
+races :: Frp m => Evt m a -> Evt m a -> Evt m a
+races (Evt a) (Evt b) = Evt $ \go ->
+  race_ (a go) (b go)
+
+-- | Execute each callback in separate thread
+forks :: Frp m => Evt m a -> Evt m a
+forks evt =
+  Evt $ \go -> runEvt evt $ void . fork . go
+
+instance Frp m => Monoid (Evt m a) where
+  mempty = never
+
+instance Frp m => Applicative (Evt m) where
+  pure a = once (pure a)
+  f <*> a = a >>= (\x -> fmap ( $ x) f)
+
+instance Frp m => Monad (Evt m) where
+  (>>=) a f = switch (fmap f a)
+
+-- | Accumulate over event stream.
+accum :: Frp m => (a -> s -> (b, s)) -> s -> Evt m a -> Evt m b
+accum f s evt = Evt $ \go -> do
+  ref <- proxyNewRef evt s
+  runEvt evt $ \x -> do
+    (b, s) <- f x <$> liftIO (readRef ref)
+    go b
+    liftIO $ writeRef ref s
+
+-- | Accumulate over event stream.
+accum' :: Frp m => (a -> s -> m (b, s)) -> s -> Evt m a -> Evt m b
+accum' f s evt = Evt $ \go -> do
+  ref <- proxyNewRef evt s
+  runEvt evt $ \x -> do
+    (b, s) <- f x =<< liftIO (readRef ref)
+    go b
+    liftIO $ writeRef ref s
+
+-- | Accumulate over event stream.
+accumMay :: Frp m => (a -> s -> Maybe (b, s)) -> s -> Evt m a -> Evt m b
+accumMay f s evt = Evt $ \go -> do
+  ref <- proxyNewRef evt s
+  runEvt evt $ \x -> do
+    mRes <- f x <$> liftIO (readRef ref)
+    forM_ mRes $ \(b, s) -> do
+      go b
+      liftIO $ writeRef ref s
+
+-- | Accumulate over event stream.
+accumMay' :: Frp m => (a -> s -> m (Maybe (b, s))) -> s -> Evt m a -> Evt m b
+accumMay' f s evt = Evt $ \go -> do
+  ref <- proxyNewRef evt s
+  runEvt evt $ \x -> do
+    mRes <- f x =<< liftIO (readRef ref)
+    forM_ mRes $ \(b, s) -> do
+      go b
+      liftIO $ writeRef ref s
+
+-- | scan over event stream. Example:
+--
+-- > naturals = scan (+) 0 pulse
+scan :: Frp m => (a -> b -> b) -> b -> Evt m a -> Evt m b
+scan f s evt = Evt $ \go -> do
+  ref <- proxyNewRef evt s
+  runEvt evt $ \x -> do
+    s <- f x <$> liftIO (readRef ref)
+    go s
+    liftIO $ writeRef ref s
+
+-- | scan over event stream with effectful function.
+scan' :: Frp m => (a -> b -> m b) -> b -> Evt m a -> Evt m b
+scan' f s evt = Evt $ \go -> do
+  ref <- proxyNewRef evt s
+  runEvt evt $ \x -> do
+    s <- f x =<< liftIO (readRef ref)
+    go s
+    liftIO $ writeRef ref s
+
+-- | scan combined with filter. If accumulator function produces @Nothing@ on event then
+-- that event is ignored and state is kept to previous state.
+scanMay :: Frp m => (a -> b -> Maybe b) -> b -> Evt m a -> Evt m b
+scanMay f s evt = Evt $ \go -> do
+  ref <- proxyNewRef evt s
+  runEvt evt $ \x -> do
+    ms <- f x <$> liftIO (readRef ref)
+    forM_ ms $ \s -> do
+      go s
+      liftIO $ writeRef ref s
+
+-- | scan combined with filter for effectful function. See @scanMay@ for details.
+scanMay' :: Frp m => (a -> b -> m (Maybe b)) -> b -> Evt m a -> Evt m b
+scanMay' f s evt = Evt $ \go -> do
+  ref <- proxyNewRef evt s
+  runEvt evt $ \x -> do
+    ms <- f x =<< liftIO (readRef ref)
+    forM_ ms $ \s -> do
+      go s
+      liftIO $ writeRef ref s
+
+-- | Iterates over event stream. It's like scan but it ignores the values of underying stream
+-- and starts with initial value as first element.
+iterates :: Frp m => (a -> a) -> a -> Evt m b -> Evt m a
+iterates f val evt = Evt $ \go -> do
+  ref <- proxyNewRef evt val
+  runEvt evt $ \_ -> do
+    s <- liftIO (readRef ref)
+    go s
+    liftIO $ writeRef ref (f s)
+
+withIterates :: Frp m => (a -> a) -> a -> Evt m b -> Evt m (a, b)
+withIterates f val evt = Evt $ \go -> do
+  ref <- proxyNewRef evt val
+  runEvt evt $ \x -> do
+    s <- liftIO (readRef ref)
+    go (s, x)
+    liftIO $ writeRef ref (f s)
+
+
+-- | Effectful version for @iterates@.
+iterates' :: Frp m => (a -> m a) -> a -> Evt m b -> Evt m a
+iterates' f val evt = Evt $ \go -> do
+  ref <- proxyNewRef evt val
+  runEvt evt $ \_ -> do
+    s <- liftIO (readRef ref)
+    go s
+    liftIO . writeRef ref =<< f s
+
+instance (Frp m, Num a) => Num (Dyn m a) where
+  fromInteger = pure . fromInteger
+  (+) = liftA2 (+)
+  (*) = liftA2 (*)
+  (-) = liftA2 (-)
+  negate = fmap negate
+  abs = fmap abs
+  signum = fmap signum
+
+instance (Frp m, Fractional a) => Fractional (Dyn m a) where
+  fromRational = pure . fromRational
+  recip = fmap recip
+
+instance (Frp m, Semigroup a) => Semigroup (Dyn m a) where
+  (<>) = liftA2 (<>)
+
+instance (Frp m, Monoid a) => Monoid (Dyn m a) where
+  mempty = pure mempty
+
+instance (Frp m, IsString a) => IsString (Dyn m a) where
+  fromString = pure . fromString
+
+-- | Reads current dynamic value.
+readDyn :: Frp m => DynRef m a -> m a
+readDyn (ConstRef val) = pure val
+readDyn (DynRef extract ref _ _) = do
+  s <- liftIO (readRef ref)
+  extract s
+
+-- | Shuts down the background process for dynamic and releases resulrces for
+-- event stream that drives the dynamic.
+cancelDyn :: Frp m => DynRef m a -> m ()
+cancelDyn (ConstRef _) = pure ()
+cancelDyn (DynRef _ _ tid release) = killThread tid >> release
+
+-- | Executes dynamic for observation. The dynamic is step-wise constant
+-- function that is driven by some event stream. The function runs the event stream
+-- process in background and samples the updated state.
+--
+-- We can observe the value with @readDyn@. We need to shut down the stream when
+-- we no longer need it with @cancelDyn@ function.
+runDyn :: Frp m => Dyn m a -> m (DynRef m a)
+runDyn (ConstDyn val) = pure (ConstRef val)
+runDyn dyn@(Dyn extract evt init release) = do
+  ref <- proxyNewRefDyn dyn =<< init
+  tid <- fork $ runEvt evt $ \s -> do
+    liftIO $ writeRef ref s
+  pure (DynRef extract ref tid release)
+
+-- | Turns event stream to dynamic. It holds the values of
+-- events until the next event happen. It starts with initial value.
+--
+-- > hold initVal events = ...
+hold :: Frp m => a -> Evt m a -> Dyn m a
+hold s evt = Dyn pure evt (pure s) (pure ())
+
+-- | Counts how many events accured so far on the stream.
+count :: Frp m => Evt m a -> Evt m Int
+count = scan (const succ) 0
+
+withCount :: Frp m => Evt m a -> Evt m (Int, a)
+withCount = accum (\a b -> ((b, a), succ b)) 1
+
+-- | Turns dynamic into event stream of underlying events
+-- that trigger dynamic updates.
+unhold :: Frp m => Dyn m a -> Evt m a
+unhold (ConstDyn val) = Evt $ \go -> go val
+unhold (Dyn extract evts init release) = Evt $ \go -> do
+  go =<< extract =<< init
+  runEvt evts (go <=< extract) `finally` release
+
+-- | scans over event stream and converts it to dynamic.
+scanD :: Frp m => (a -> b -> b) -> b -> Evt m a -> Dyn m b
+scanD f s evt = hold s (scan f s evt)
+
+-- | Accumulates the values with event stream that produce functions.
+accumB :: Frp m => a -> Evt m (a -> a) -> Dyn m a
+accumB a evt = scanD ($) a evt
+
+-- | Dynamic scan that can also filter out events. If Nothing is produced then the event is skipped.
+scanMayD :: Frp m => (a -> b -> Maybe b) -> b -> Evt m a -> Dyn m b
+scanMayD f s evt = hold s (scanMay f s evt)
+
+-- | Adds some procedure to callback. Procedure is called prior to callback execution.
+foreach :: Frp m => (a -> m ()) -> Evt m a -> Evt m a
+foreach call evt = Evt $ \go ->
+  runEvt evt $ \x -> do
+    call x
+    go x
+
+-- | Adds some procedure to callback. Procedure is called after callback execution.
+posteach :: Frp m => (a -> m ()) -> Evt m a -> Evt m a
+posteach call evt = Evt $ \go ->
+  runEvt evt $ \x -> do
+    go x
+    call x
+
+--------------------------------------------------------------------------------
+-- applications
+
+-- | Applies a function to event stream value. The function is sampled
+-- from dynamic process.
+apply :: Frp m => Dyn m (a -> b) -> Evt m a -> Evt m b
+apply dyn evt = Evt $ \go -> do
+  ref <- runDyn dyn
+  runEvt evt (\b -> do
+      go . ($ b) =<< readDyn ref
+    )
+    `finally` cancelDyn ref
+
+-- | Effectful variant of @apply@.
+apply' :: Frp m => Dyn m (a -> m b) -> Evt m a -> Evt m b
+apply' dyn evt = Evt $ \go -> do
+  ref <- runDyn dyn
+  runEvt evt (\b -> do
+    (\f -> go =<< f b) =<< readDyn ref)
+    `finally` cancelDyn ref
+
+-- | Infix variant of @apply@
+(<@>) :: Frp m => Dyn m (a -> b) -> Evt m a -> Evt m b
+(<@>) = apply
+
+-- | Infix variant of @snap@.
+(<@) :: Frp m => Dyn m a -> Evt m b -> Evt m a
+(<@) = snap
+
+-- | Apply combined with filter.
+applyMay :: Frp m => Dyn m (a -> Maybe b) -> Evt m a -> Evt m b
+applyMay dyn evt = Evt $ \go -> do
+  ref <- runDyn dyn
+  runEvt evt (\b -> do
+    mapM_ go . ($ b) =<< readDyn ref)
+    `finally` cancelDyn ref
+
+-- | Effectful @applyMay@.
+applyMay' :: Frp m => Dyn m (a -> m (Maybe b)) -> Evt m a -> Evt m b
+applyMay' dyn evt = Evt $ \go -> do
+  ref <- runDyn dyn
+  runEvt evt (\b -> do
+    (\f -> mapM_ go =<< f b) =<< readDyn ref)
+    `finally` cancelDyn ref
+
+-- | Snapshot of dynamic process with event stream. All values
+-- in the event stream are substituted with current value of dynamic.
+snap :: Frp m => Dyn m a -> Evt m b -> Evt m a
+snap dyn evt = apply (const <$> dyn) evt
+
+-- | Attach element from dyn to event stream.
+attach :: Frp m => Dyn m a-> Evt m b -> Evt m (a, b)
+attach dyn evt = attachWith (,) dyn evt
+
+-- | Kind of @zipWith@ function for dynamics and event streams.
+attachWith :: Frp m => (a -> b -> c) -> Dyn m a -> Evt m b -> Evt m c
+attachWith f dyn evt = apply (f <$> dyn) evt
+
+-- | Attach with filtering. When @Nothing@ is produced event is omitted from the stream.
+attachWithMay :: Frp m => (a -> b -> Maybe c) -> Dyn m a -> Evt m b -> Evt m c
+attachWithMay f dyn evt = applyMay (f <$> dyn) evt
+
+--------------------------------------------------------------------------------
+-- filters
+
+-- | Map with filtering. When @Nothing@ is produced event is omitted from the stream.
+mapMay :: Frp m => (a -> Maybe b) -> Evt m a -> Evt m b
+mapMay f evt = Evt $ \go -> runEvt evt (mapM_ go . f)
+
+-- | Effectful @mapMay@
+mapMay' :: Frp m => (a -> m (Maybe b)) -> Evt m a -> Evt m b
+mapMay' f evt = Evt $ \go -> runEvt evt (mapM_ go <=< f)
+
+-- | Filtering of the event strewams. Only events that produce True remain in the stream.
+filters :: Frp m => (a -> Bool) -> Evt m a -> Evt m a
+filters f evt = Evt $ \go -> runEvt evt (\x -> when (f x) (go x))
+
+-- | Effectful filtering for event streams.
+filters' :: Frp m => (a -> m Bool) -> Evt m a -> Evt m a
+filters' f evt = Evt $ \go -> runEvt evt (\x -> (\cond -> when cond (go x)) =<< f x)
+
+-- | Filters based on Maybe. If @Nothing@ is produced forthe event it is omitted from the stream.
+filterJust :: Frp m => Evt m (Maybe a) -> Evt m a
+filterJust evt = Evt $ \go -> runEvt evt (mapM_ go)
+
+-- | Filters with dynamic. When dynamic is true events pass through and when it's false
+-- events are omitted.
+whens :: Frp m => Dyn m Bool -> Evt m a -> Evt m a
+whens dyn evt = Evt $ \go -> do
+  ref <- runDyn dyn
+  runEvt evt $ \b -> do
+    a <- readDyn ref
+    when a (go b)
+
+-- | Splits the either event stream.
+splits :: Frp m => Evt m (Either a b) -> (Evt m a, Evt m b)
+splits evt = (lefts evt, rights evt)
+
+-- | Gets all left events from the stream
+lefts :: Frp m => Evt m (Either a b) -> Evt m a
+lefts evt = mapMay (either Just (const Nothing)) evt
+
+-- | Gets all right events from the stream
+rights :: Frp m => Evt m (Either a b) -> Evt m b
+rights evt = mapMay (either (const Nothing) Just) evt
+
+-- | Takes only so many events from the stream
+takes :: Frp m => Int -> Evt m a -> Evt m a
+takes n evt = Evt $ \go -> do
+  ref <- proxyNewRef evt 0
+  waitAsync $ do
+    runEvt evt $ \x -> do
+      cur <- liftIO (readRef ref)
+      when (cur < n) $ do
+        go x
+        when (cur == n - 1) stopSelf
+        liftIO $ writeRef ref (cur + 1)
+
+-- | Drops first so many events from the stream
+drops :: Frp m => Int -> Evt m a -> Evt m a
+drops n evt = Evt $ \go -> do
+  tv <- proxyNewRef evt n
+  runEvt evt $ \x -> do
+    cur <- liftIO (readRef tv)
+    if (cur <= 0)
+      then go x
+      else liftIO (modifyRef tv pred)
+
+stopSelf :: Frp m => m ()
+stopSelf = killThread =<< myThreadId
+
+waitStop :: Frp m => Async a -> m ()
+waitStop x = void $ liftIO $ waitCatch x
+
+waitAsync :: Frp m => m () -> m ()
+waitAsync act = do
+  tid <- async act
+  waitStop tid
+
+-- | Takes events only while predicate is true.
+takesWhile :: Frp m => (a -> Bool) -> Evt m a -> Evt m a
+takesWhile pred evt = Evt $ \go -> do
+  waitAsync $ do
+    runEvt evt $ \x -> do
+      if (pred x)
+        then go x
+        else stopSelf
+
+-- | Drops events while predicate is true.
+dropsWhile :: Frp m => (a -> Bool) -> Evt m a -> Evt m a
+dropsWhile pred evt = Evt $ \go -> do
+  tv <- proxyNewRef evt True
+  runEvt evt $ \x -> do
+    cur <- liftIO (readRef tv)
+    if cur
+      then
+        unless (pred x) $ do
+          liftIO $ writeRef tv False
+          go x
+      else go x
+
+-- | Takes elements from the list by index. If index is out of bounds the event is omitted.
+listAt :: Frp m => [a] -> Evt m Int -> Evt m a
+listAt vals evt = mapMay (vec V.!?) evt
+  where
+    vec = V.fromList vals
+
+-- | Turns event stream to toggle stream. It produce cyclic sequence of [True, False]
+toToggle :: Frp m => Evt m a -> Evt m Bool
+toToggle = iterates not True
+
+-- | Cycles the values in the list over event sream.
+cycles :: Frp m => [a] -> Evt m b -> Evt m a
+cycles vals evt = fmap (vec V.!) $ iterates ((`mod` len) . succ) 0 evt
+  where
+    vec = V.fromList vals
+    len = V.length vec
+
+-- | Sums all the elements in the event stream
+sums :: (Frp m, Num a) => Evt m a -> Evt m a
+sums = scan (+) 0
+
+-- | Integrates signal of vectors with given time step
+integrate :: (Frp m, VectorSpace v, Real (Scalar v), Fractional (Scalar v)) => (Scalar v) -> Dyn m v -> Dyn m v
+integrate dt dyn =
+  hold zeroV $ scan (^+^) zeroV (attachWith (\v k -> realToFrac k *^ v) dyn (ticks (realToFrac dt)))
+
+-- | More accurate integration of signal of vectors with given time step
+integrate2 :: (Frp m, VectorSpace v, Real (Scalar v), Fractional (Scalar v)) => (Scalar v) -> Dyn m v -> Dyn m v
+integrate2 dt dyn =
+  hold zeroV $ fmap snd $ scan go (Nothing, zeroV) (attach dyn (ticks (realToFrac dt)))
+  where
+    go (v, h) (mPrev, res) = ((Just (v, h), ) . (res ^+^ )) $ case mPrev of
+      Nothing       -> realToFrac h *^ v
+      Just (v0, h0) -> (realToFrac h * 0.5) *^ (v0 ^+^ v)
+
+-- | Sums all points in the signal with given time step
+sumD :: (Frp m, Num a) => NominalDiffTime -> Dyn m a -> Dyn m a
+sumD dt dyn = hold 0 $ sums (snap dyn (pulse dt))
+
+
+-- | Finds the product of all elements in the event stream.
+products :: (Frp m, Num a) => Evt m a -> Evt m a
+products = scan (*) 1
+
+-- | Monoidal append of all elements in the stream
+appends :: (Frp m, Monoid a) => Evt m a -> Evt m a
+appends = scan (flip (<>)) mempty
+
+-- | Same as foldMap only for streams.
+foldMaps :: (Frp m, Monoid b) => (a -> b) -> Evt m a -> Evt m b
+foldMaps f = appends . fmap f
+
+-- | Monoidal fold for event streams, note that stream have to be finite for
+-- the function to complete
+folds :: (Frp m, Monoid a) => Evt m a -> m a
+folds = foldls (<>) mempty
+
+-- | Left fold for event streams, note that stream have to be finite for
+-- the function to complete
+foldls :: (Frp m) => (b -> a -> b) -> b -> Evt m a -> m b
+foldls f s evt = do
+  ref <- proxyNewRef evt s
+  runEvt evt $ \x -> liftIO $ modifyRef ref $ flip f x
+  liftIO $ readRef ref
+
+-- | Effectful left fold
+foldls' :: (Frp m) => (b -> a -> m b) -> b -> Evt m a -> m b
+foldls' f s evt = do
+  ref <- proxyNewRef evt s
+  runEvt evt $ \x -> liftIO . writeRef ref =<< flip f x =<< liftIO (readRef ref)
+  liftIO $ readRef ref
+
+-- | Right fold for event streams, note that stream have to be finite for
+-- the function to complete
+foldrs :: (Frp m) => (a -> b -> b) -> b -> Evt m a -> m b
+foldrs f s evt = do
+  ref <- proxyNewRef evt s
+  runEvt evt $ \x -> liftIO $ modifyRef ref $ f x
+  liftIO $ readRef ref
+
+-- | Effectful right fold
+foldrs' :: (Frp m) => (a -> b -> m b) -> b -> Evt m a -> m b
+foldrs' f s evt = do
+  ref <- proxyNewRef evt s
+  runEvt evt $ \x -> liftIO . writeRef ref =<< f x =<< liftIO (readRef ref)
+  liftIO $ readRef ref
+
+-- | Starts event stream process and as callback prints it values.
+prints :: (Frp m, Show a) => Evt m a -> m ()
+prints evt = runEvt evt (liftIO . print)
+
+-- | Starts event stream process and as callback prints it values.
+putStrLns :: (Frp m) => Evt m String -> m ()
+putStrLns evt = runEvt evt (liftIO . putStrLn)
+
+-- | Stream of user inputs
+getLines :: Frp m => Evt m String
+getLines = once (liftIO getLine)
+
+-- | Queries the event stream form dynamic and runs it all next event streams are ignored.
+switchDyn :: Frp m => Dyn m (Evt m a) -> Evt m a
+switchDyn dyn = Evt $ \go -> do
+  ref <- runDyn dyn
+  evt <- readDyn ref
+  runEvt evt go
+
+-- | Joins event stream of streams. If stream is started it runs until the end.
+joins :: Frp m => Evt m (Evt m a) -> Evt m a
+joins evt = Evt $ \go ->
+  runEvt evt $ \e -> void $ fork $ runEvt e go
+
+-- | Recursion on event streams. As event streams are functions we can not use
+-- normal recursion that haskell provides. It will stuck the execution.
+-- But we can use @fix1@ to create event stream that feeds back the events to itself.
+--
+-- Note that any sort of recursion can be implemented with @fix1@.
+-- For example if we need 3-recursive event stream:
+--
+--  > fix3 ::
+--  >      (Evt m a -> Evt m b -> Evt m c -> m (Evt m a, Evt m b, Evt m c))
+--  >   -> (Evt m a, Evt m b, Evt m c)
+--
+-- we can use sum tpye tags
+-- to join it to single stream:
+--
+-- > data Tag a b c = TagA a | TagB b | TagC c
+--
+-- > fix3 f = unwrap $ fix1 g
+-- >   where
+-- >      g x = wrap <$> f (unwrapA x) (unwrapB x) (unwrapC x)
+-- >
+-- >      wrap a b c = mconcat [TagA <$> a, TagB <$> b, TagC <$> c]
+-- >      unwrap evt = (unwrapA evt, unwrapB evt, unwrapC evt)
+-- >
+-- >      unwrapA = flip mapMay $ \x -> case x of
+-- >                                  TagA a -> Just a
+-- >                                  _      -> Nothing
+--
+-- We can use this trck with any number of streams. There are helper functions: @fix2@, @fix3@, @fix4@
+fix1 :: Frp m => (Evt m a -> m (Evt m a)) -> Evt m a
+fix1 f = Evt $ \go -> do
+  chan <- liftIO U.newChan
+  let evt = uchanEvt (fst chan)
+  evt' <- f evt
+  runEvt evt' $ \x -> do
+    liftIO $ U.writeChan (fst chan) x
+    go x
+
+-- | Recursion for binary functions
+fix2 :: Frp m => (Evt m a -> Evt m b -> m (Evt m a, Evt m b)) -> (Evt m a, Evt m b)
+fix2 f = splits $ fix1 g
+  where
+    g x = wrap <$> f (lefts x) (rights x)
+    wrap (a, b) = (Left <$> )a <> (Right <$> b)
+
+data Tag3 a b c = TagA3 a | TagB3 b | TagC3 c
+
+-- | Recursion for ternary functions
+fix3 :: Frp m
+  => (Evt m a -> Evt m b -> Evt m c -> m (Evt m a, Evt m b, Evt m c))
+  -> (Evt m a, Evt m b, Evt m c)
+fix3 f = unwrap $ fix1 g
+  where
+    g x = wrap <$> f (unwrapA x) (unwrapB x) (unwrapC x)
+    wrap (a, b, c) = (TagA3 <$> a) <> (TagB3 <$> b) <> (TagC3 <$> c)
+
+    unwrap x = (unwrapA x, unwrapB x, unwrapC x)
+
+    unwrapA = mapMay $ \case
+                TagA3 a -> Just a
+                _       -> Nothing
+
+    unwrapB = mapMay $ \case
+                TagB3 a -> Just a
+                _       -> Nothing
+
+    unwrapC = mapMay $ \case
+                TagC3 a -> Just a
+                _       -> Nothing
+
+
+data Tag4 a b c d = TagA4 a | TagB4 b | TagC4 c | TagD4 d
+
+-- | Recursion for functions of four arguments
+fix4 :: Frp m =>
+     (Evt m a -> Evt m b -> Evt m c -> Evt m d -> m (Evt m a, Evt m b, Evt m c, Evt m d))
+  -> (Evt m a, Evt m b, Evt m c, Evt m d)
+fix4 f = unwrap $ fix1 g
+  where
+    g x = wrap <$> f (unwrapA x) (unwrapB x) (unwrapC x) (unwrapD x)
+    wrap (a, b, c, d) = (TagA4 <$> a) <> (TagB4 <$> b) <> (TagC4 <$> c) <> (TagD4 <$> d)
+
+    unwrap x = (unwrapA x, unwrapB x, unwrapC x, unwrapD x)
+
+    unwrapA = mapMay $ \case
+                TagA4 a -> Just a
+                _       -> Nothing
+
+    unwrapB = mapMay $ \case
+                TagB4 a -> Just a
+                _       -> Nothing
+
+    unwrapC = mapMay $ \case
+                TagC4 a -> Just a
+                _       -> Nothing
+
+    unwrapD = mapMay $ \case
+                TagD4 a -> Just a
+                _       -> Nothing
+
+-- | Flattens event stream producer by switching between event streams.
+-- When next event stream happens it shuts down the previous one.
+switch :: Frp m => Evt m (Evt m a) -> Evt m a
+switch evts = Evt $ \go -> do
+  tidRef <- proxyNewRef evts Nothing
+  let stop = mapM_ killThread =<< liftIO (readRef tidRef)
+  lock <- newEmptyMVar  -- we use this lock to make sure that next process
+                        -- does not start before we saved it's threadId for stopping.
+  runEvt evts (\evt -> do
+    stop
+    tid <- fork (takeMVar lock >> runEvt evt go)  -- delay until threadId is saved
+    liftIO $ writeRef tidRef (Just tid)           -- save tid (for stopping)
+    putMVar lock ()                               -- start the event process
+    ) `finally` stop
+
+-- | Switches between dynamic producers.
+switchD :: Frp m => Dyn m a -> Evt m (Dyn m a) -> Dyn m a
+switchD d evts = Dyn extract resEvt init (pure ())
+  where
+    init    = runDyn d
+    extract = readDyn
+
+    resEvt = Evt $ \go -> do
+      runEvt evts $ \dyn -> do
+        ref <- runDyn dyn
+        go ref `finally` cancelDyn ref
+
+---------------------------------------------------------
+-- channels
+
+-- | Creates the event stream that listens to MVar based channel.
+-- If any value is put chan the event stream fires the callback.
+mchanEvt :: (Frp m) => M.Chan a -> Evt m a
+mchanEvt chan = Evt $ \go -> do
+  chan <- liftIO $ M.dupChan chan
+  loop chan go
+  where
+    loop chan go = do
+      a <- liftIO $ M.readChan chan
+      go a
+      loop chan go
+
+-- | Creates the event stream that listens to @TChan@ based channel.
+-- If any value is put chan the event stream fires the callback.
+tchanEvt :: (Frp m) => TChan a -> Evt m a
+tchanEvt chan = Evt $ \go -> do
+  chan <- liftIO $ atomically $ dupTChan chan
+  loop chan go
+  where
+    loop chan go = do
+      a <- liftIO $ atomically $ readTChan chan
+      go a
+      loop chan go
+
+-- | Creates the event stream that listens to unagi channel (package @unagi-chan@).
+-- If any value is put chan the event stream fires the callback.
+uchanEvt :: (Frp m) => InChan a -> Evt m a
+uchanEvt chan = Evt $ \go -> do
+  chan <- liftIO $ U.dupChan chan
+  loop chan go
+  where
+    loop chan go = do
+      a <- liftIO $ U.readChan chan
+      go a
+      loop chan go
+
+type UChan a = (U.InChan a, U.OutChan a)
+
+--------------------------------------------------------------------------------
+
+proxyNewRef :: Frp m => Evt m a -> b -> m (Ref m b)
+proxyNewRef _ v = liftIO $ newRef v
+
+proxyNewRefDyn :: Frp m => Dyn m a -> b -> m (Ref m b)
+proxyNewRefDyn _ v = liftIO $ newRef v
+
+proxyFunRes :: (a -> b) -> b
+proxyFunRes _ = undefined
+
+---------------------------------------------------------------------------
+-- utilities
+
+-- | Queries current time periodically with given period in seconds.
+clock :: Frp m => NominalDiffTime -> Evt m UTCTime
+clock t = Evt $ \go -> periodic t $ go =<< liftIO getCurrentTime
+
+-- | Produces pulse events with given period in seconds.
+pulse :: Frp m => NominalDiffTime -> Evt m ()
+pulse t = Evt $ \go -> periodic t (go ())
+
+-- | Produces pulse events with given period in seconds
+-- and also tells how many seconds exactly has passed.
+-- It can be useful for simulations of models that are based on differential equations.
+-- As event streams carries how much time has passed between simulation steps.
+ticks :: Frp m => NominalDiffTime -> Evt m NominalDiffTime
+ticks t = Evt $ \go -> do
+  startRef <- liftIO $ newIORef =<< getCurrentTime
+  periodic t $ do
+    dt <- liftIO $ do
+      cur   <- getCurrentTime
+      start <- readIORef startRef
+      writeIORef startRef cur
+      pure $ cur `diffUTCTime` start
+    go dt
+
+-- | Timer behaves like tocks only it produces accumulated time since beginning
+-- of the process. It calculates them by querying current time and suntracting start time from it.
+--
+-- It can be though of as:
+--
+-- > sums ticks
+timer :: Frp m => NominalDiffTime -> Evt m NominalDiffTime
+timer t = Evt $ \go -> do
+  start <- liftIO getCurrentTime
+  periodic t $ go =<< liftIO ((`diffUTCTime` start) <$> getCurrentTime)
+
+-- | Timer as dynamic signal.
+timerD :: Frp m => NominalDiffTime -> Dyn m NominalDiffTime
+timerD t = hold 0 $ timer t
+
+{-# NOINLINE periodic #-}
+-- | Periodically triggers callback.
+periodic :: MonadIO m => NominalDiffTime -> m () -> m ()
+periodic dur proc = do
+  startRef <- liftIO $ newIORef =<< getCurrentTime
+  fix $ \next -> do
+    proc
+    time <- liftIO $ do
+      last <- readIORef startRef
+      cur  <- getCurrentTime
+      let dt = max 0 $ dur - (cur `diffUTCTime` last)
+      writeIORef startRef (addUTCTime dt cur)
+      pure dt
+    sleep time
+    next
+
+-- | Stop the thread for some time in seconds.
+sleep :: MonadIO m => NominalDiffTime -> m ()
+sleep dt = liftIO . D.delay $ toMicroseconds dt
+
+-- | Convert time to microseconds
+toMicroseconds :: NominalDiffTime -> Integer
+toMicroseconds t = ceiling $ toRational t * 1000000
+
+--------------------------------------------------------------------------------
+
+-- | Substitutes values in event stream with random values.
+toRandom :: forall m a b . (Frp m, Random b) => Evt m a -> Evt m b
+toRandom evt = Evt $ \go -> do
+  tv <- proxyNewRef evt =<< liftIO newStdGen
+  runEvt evt $ \_ -> do
+    (a, g) <- liftIO $ random <$> readRef tv
+    go a
+    liftIO $ writeRef tv g
+
+-- | Substitutes values in event stream with random values from the given range.
+toRandomR :: forall m a b . (Frp m, Random b) => (b, b) -> Evt m a -> Evt m b
+toRandomR range evt = Evt $ \go -> do
+  tv <- proxyNewRef evt =<< liftIO newStdGen
+  runEvt evt $ \_ -> do
+    (a, g) <- liftIO $ randomR range <$> readRef tv
+    go a
+    liftIO $ writeRef tv g
+
+-- | Substitutes values in event stream with random values.
+withRandom :: forall m a b . (Frp m, Random b) => Evt m a -> Evt m (b, a)
+withRandom evt = Evt $ \go -> do
+  tv <- proxyNewRef evt =<< liftIO newStdGen
+  runEvt evt $ \x -> do
+    (a, g) <- liftIO $ random <$> readRef tv
+    go (a, x)
+    liftIO $ writeRef tv g
+
+-- | Substitutes values in event stream with random values from the given range.
+withRandomR :: forall m a b . (Frp m, Random b) => (b, b) -> Evt m a -> Evt m (b, a)
+withRandomR range evt = Evt $ \go -> do
+  tv <- proxyNewRef evt =<< liftIO newStdGen
+  runEvt evt $ \x -> do
+    (a, g) <- liftIO $ randomR range <$> readRef tv
+    go (a, x)
+    liftIO $ writeRef tv g
+
+-- | Picks at random one element from the list
+oneOf :: Frp m => [a] -> Evt m b -> Evt m a
+oneOf xs evt = listAt xs $ toRandomR (0, len - 1) evt
+  where
+    len = length xs
+
+-- | Picks at random one element from the list
+withOneOf :: Frp m => [a] -> Evt m b -> Evt m (a, b)
+withOneOf xs evt = first (vec V.! ) <$> withRandomR (0, len - 1) evt
+  where
+    len = V.length vec
+    vec = V.fromList xs
+
+-- | Picks at random one element from the list. We also provide distribution of events.
+-- Probability to pick up the element. Sum of probabilities should equal to 1.
+freqOf :: (R.MonadRandom m, Frp m) => Dyn m [(a, Rational)] -> Evt m b -> Evt m a
+freqOf dynVals evts = applyMay' ((\vals -> const (go vals)) <$> dynVals) evts
+  where
+    go vals = R.fromListMay vals
+
+-- | Picks at random one element from the list. We also provide distribution of events.
+-- Probability to pick up the element. Sum of probabilities should equal to 1.
+withFreqOf :: (R.MonadRandom m, Frp m) => Dyn m [(a, Rational)] -> Evt m b -> Evt m (a, b)
+withFreqOf dynVals evts = applyMay' (go <$> dynVals) evts
+  where
+    go vals x = fmap (fmap ((, x))) $ R.fromListMay vals
+
+-- | Skips at random elements from the list. We provide frequency to skip events with dynamic first argument.
+randSkip :: Frp m => Dyn m Double -> Evt m a -> Evt m a
+randSkip prob evt = randSkipBy (const <$> prob) evt
+
+-- | Skips elements at random. The probability to skip element depends on the element itself.
+randSkipBy :: Frp m => Dyn m (a -> Double) -> Evt m a -> Evt m a
+randSkipBy  prob evt = attachWithMay f prob $ withRandomR (0, 1 :: Double) evt
+  where
+    f getProb (curProb, a)
+      | curProb < getProb a  = Nothing
+      | otherwise            = Just a
+
+--------------------------------------------------------------------------------
+
+-- | Delays in the thread of execution. Note that it can interfere
+-- and screw up functions like clock, timer, pulse, ticks
+delay :: Frp m => NominalDiffTime -> Evt m a -> Evt m a
+delay dt evt = Evt $ \go ->
+  runEvt evt $ \x -> sleep dt >> go x
+
+-- | Delays in background by forking on each event.
+-- Note tht if delayed event was put into background prior
+-- to stopping of the main event stream it will fire anyway.
+-- There is no way to stop it.
+delayFork :: Frp m => NominalDiffTime -> Evt m a -> Evt m a
+delayFork dt evt = Evt $ \go ->
+  runEvt evt $ \x -> void $ fork $ sleep dt >> go x
+
+--------------------------------------------------------------------------------
+-- effectful functor
+
+class FunctorM f where
+  fmap' :: Frp m => (a -> m b) -> f m a -> f m b
+
+instance FunctorM Evt where
+  fmap' f evt = Evt $ \go -> runEvt evt $ \x -> go =<< f x
+
+instance FunctorM Dyn where
+  fmap' f (ConstDyn a)                = Dyn f never (pure a) (pure ())
+  fmap' f (Dyn extract evt s release) = Dyn (f <=< extract) evt s release
+
+--------------------------------------------------------------------------------
+-- Boolean instances
+
+instance (Boolean b, Frp m) => Boolean (Dyn m b) where
+  true = pure true
+  false = pure false
+  notB = fmap notB
+  (&&*) = liftA2 (&&*)
+  (||*) = liftA2 (||*)
+
+type instance BooleanOf (Dyn m a) = Dyn m (BooleanOf a)
+
+instance (Frp m, IfB a) => IfB (Dyn m a) where
+  ifB = liftA3 ifB
+
+instance (EqB a, Frp m) => EqB (Dyn m a) where
+  (==*) = liftA2 (==*)
+
+instance (OrdB a, Frp m) => OrdB (Dyn m a) where
+  (<*) = liftA2 (<*)
+  (>*) = liftA2 (>*)
+  (<=*) = liftA2 (<=*)
+  (>=*) = liftA2 (>=*)
+
+--------------------------------------------------------------------------------
+-- Vector Space instances
+
+instance (AdditiveGroup a, Frp m) => AdditiveGroup (Dyn m a) where
+  zeroV = pure zeroV
+  (^+^) = liftA2 (^+^)
+  (^-^) = liftA2 (^-^)
+  negateV = fmap negateV
+
+instance (VectorSpace a, Frp m) => VectorSpace (Dyn m a) where
+  type Scalar (Dyn m a) = Dyn m (Scalar a)
+  (*^) = liftA2 (*^)
+
+instance (AffineSpace p, Frp m) => AffineSpace (Dyn m p) where
+  type Diff (Dyn m p) = Dyn m (Diff p)
+  (.-.) = liftA2 (.-.)
+  (.+^) = liftA2 (.+^)
+
+class BasisArity v where
+  basisArity :: v -> Int
+
+instance BasisArity Float where
+  basisArity _ = 1
+
+instance BasisArity Double where
+  basisArity _ = 1
+
+instance (BasisArity a, BasisArity b) =>  BasisArity (a, b) where
+  basisArity v = basisArity (proxyA v) + basisArity (proxyB v)
+    where
+      proxyA :: (a, b) -> a
+      proxyA _ = undefined
+
+      proxyB :: (a, b) -> b
+      proxyB _ = undefined
+
+instance (BasisArity a, BasisArity b, BasisArity c) =>  BasisArity (a, b, c) where
+  basisArity v = basisArity (proxyA v) + basisArity (proxyB v) + basisArity (proxyC v)
+    where
+      proxyA :: (a, b, c) -> a
+      proxyA _ = undefined
+
+      proxyB :: (a, b, c) -> b
+      proxyB _ = undefined
+
+      proxyC :: (a, b, c) -> c
+      proxyC _ = undefined
+
+instance (Frp m, BasisArity v) => BasisArity (Dyn m v) where
+  basisArity v = basisArity (proxy v)
+    where
+      proxy :: Dyn m v -> v
+      proxy _ = undefined
+
+instance (BasisArity v, HasBasis v, Frp m) => HasBasis (Dyn m v) where
+  type Basis (Dyn m v) = Dyn m (Basis v)
+  basisValue = fmap basisValue
+  decompose v = fmap unTupleD $ unListD (basisArity v) $ fmap decompose v
+
+  decompose' = liftA2 decompose'
+
+unTupleD :: Frp m => Dyn m (a, b) -> (Dyn m a, Dyn m b)
+unTupleD x = (fmap fst x, fmap snd x)
+
+unListD :: Frp m => Int -> Dyn m [a] -> [Dyn m a]
+unListD n ds = fmap (\a -> fmap ( !! a) ds) [0.. pred n]
+
+instance (HasNormal v, Frp m) => HasNormal (Dyn m v) where
+  normalVec = fmap normalVec
+
+instance (HasCross2 v, Frp m) => HasCross2 (Dyn m v) where
+  cross2 = fmap cross2
+
+instance (HasCross3 v, Frp m) => HasCross3 (Dyn m v) where
+  cross3 = liftA2 cross3
+
+--------------------------------------------------------------------------------
+-- Temporal media instances
+
+instance Frp m => Melody (Evt m a) where
+  (+:+) evtA evtB = Evt $ \go -> do
+      runEvt evtA go
+      runEvt evtB go
+
+instance Frp m => Harmony (Evt m a) where
+  (=:=) = (<>)
+
+instance Frp m => Compose (Evt m a) where
+
+instance Frp m => Loop (Evt m a) where
+  loop evt = Evt $ \go -> forever (runEvt evt go)
+
+-- | Takes an event and repeats it all the time.
+forevers :: Frp m => Evt m a -> Evt m a
+forevers evt = Evt $ \go -> forever (runEvt evt go)
+
+type instance DurOf (Evt m a) = NominalDiffTime
+
+instance Frp m => Limit (Evt m a) where
+  lim t evt = Evt $ \go ->
+    race_ (runEvt evt go) (sleep t)
+
+--------------------------------------------------------------------------------
+-- Parser
+
+data St a = Final a | Cont a
+  deriving (Functor)
+
+data Parser m a b = forall s . Parser
+  { parser'init   :: s
+  , parser'modify :: (a -> s -> m (Maybe (St s)))
+  , parser'get    :: s -> m (Maybe b)
+  }
+
+runParser :: Frp m => Parser m a b -> Evt m a -> m (Maybe b)
+runParser (Parser init modify get) evt = do
+  ref <- proxyNewRef evt (Cont init)
+
+  waitAsync $ do
+    runEvt evt $ \x -> do
+      st <- liftIO $ readRef ref
+      case st of
+        Final s -> stopSelf
+        Cont s  -> do
+          mS' <- modify x s
+          forM_ mS' $ \case
+            Cont s  -> liftIO $ writeRef ref (Cont s)
+            Final s -> liftIO $ do
+              writeRef ref (Final s)
+              stopSelf
+
+  st <- liftIO (readRef ref)
+  case st of
+    Final s -> get s
+    _       -> pure Nothing
+
+heads :: Frp m => Evt m a -> m a
+heads evt = do
+  ref <- proxyNewRef evt Nothing
+  waitAsync $ do
+    runEvt evt $ \x -> do
+      liftIO $ writeRef ref (Just x)
+      stopSelf
+  fromJust <$> liftIO (readRef ref)
+
+-- | Reads single event
+takeP :: Frp m => Parser m a b -> Evt m a -> Evt m b
+takeP (Parser init modify get) evt = Evt $ \go -> do
+  ref <- proxyNewRef evt init
+  waitAsync $ do
+    runEvt evt $ \x -> do
+      s <- liftIO $ readRef ref
+      mS' <- modify x s
+      forM_ mS' $ \case
+        Cont s'  -> liftIO $ writeRef ref s'
+        Final s' -> do
+          mapM_ go =<< get s'
+          stopSelf
+
+cycleP :: Frp m => Parser m a b -> Evt m a -> Evt m b
+cycleP (Parser init modify get) evt = Evt $ \go -> do
+  ref <- proxyNewRef evt init
+  waitAsync $ do
+    runEvt evt $ \x -> do
+      s <- liftIO $ readRef ref
+      mS' <- modify x s
+      forM_ mS' $ \case
+        Cont s'  -> liftIO $ writeRef ref s'
+        Final s' -> do
+          mapM_ go =<< get s'
+          liftIO $ writeRef ref init
+
+-- | Takes first element of the event stream and shuts the stream down.
+headP :: Frp m => Parser m a a
+headP = Parser init modify get
+  where
+    init = Nothing
+    modify a _ = pure $ Just (Final (Just a))
+    get = pure
+
+maybeP :: Frp m => (a -> Maybe b) -> Parser m a b
+maybeP f = Parser init modify get
+  where
+    init = Nothing
+    modify a _ = pure $ fmap (Final . Just) $ f a
+    get = pure
+
+instance Frp m => Functor (Parser m a) where
+  fmap f (Parser init modify get) = Parser init modify (fmap (fmap f) . get)
+
+instance Frp m => Applicative (Parser m a) where
+  pure a = Parser () (\_ _ -> pure (Just (Final ()))) (const $ pure $ Just a)
+  (Parser initF modifyF getF) <*> (Parser initA modifyA getA) = Parser initRes modifyRes getRes
+    where
+      initRes = (Cont initF, Cont initA)
+
+      modifyRes inp (sf, sa) = case sf of
+        Cont f -> do
+          mF' <- modifyF inp f
+          pure $ fmap (Cont . (, sa)) mF'
+        Final f ->
+          case sa of
+            Cont a -> do
+              mA' <- modifyA inp a
+              pure $ flip fmap mA' $ \case
+                  Cont a'  -> Cont (Final f, Cont a')
+                  Final a' -> Final (Final f, Final a')
+            Final a -> pure (Just (Final (sf, sa)))
+
+      getRes = \case
+        (Final f, Final a) -> do
+          mf <- getF f
+          ma <- getA a
+          pure (mf <*> ma)
+        _                  -> pure Nothing
+
+
+-- | Create a new Event and a function that will cause the Event to fire
+newTriggerEvt :: (Frp m, MonadIO io) => m (Evt m a, a -> io ())
+newTriggerEvt = do
+  chan <- liftIO U.newChan
+  pure (uchanEvt (fst chan), liftIO . U.writeChan (fst chan))
+
diff --git a/src/Dyna/Ref.hs b/src/Dyna/Ref.hs
new file mode 100644
--- /dev/null
+++ b/src/Dyna/Ref.hs
@@ -0,0 +1,26 @@
+module Dyna.Ref(
+  IsRef(..),
+) where
+
+import Data.IORef
+import Control.Concurrent.STM
+import Control.Concurrent.STM.TVar
+
+class IsRef ref where
+  newRef    :: a -> IO (ref a)
+  readRef   :: ref a -> IO a
+  writeRef  :: ref a -> a -> IO ()
+  modifyRef :: ref a -> (a -> a) -> IO ()
+
+instance IsRef IORef where
+  newRef = newIORef
+  readRef = readIORef
+  writeRef = writeIORef
+  modifyRef = modifyIORef'
+
+instance IsRef TVar where
+  newRef = newTVarIO
+  readRef = readTVarIO
+  writeRef ref v = atomically $ writeTVar ref v
+  modifyRef ref f = atomically $ modifyTVar' ref f
+
diff --git a/test/Spec.hs b/test/Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec.hs
@@ -0,0 +1,2 @@
+main :: IO ()
+main = putStrLn "Test suite not yet implemented"
