diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
 
-Tidal [![Build Status](https://travis-ci.org/tidalcycles/Tidal.svg?branch=master)](https://travis-ci.org/tidalcycles/Tidal)
+Tidal [![Build Status](https://travis-ci.org/tidalcycles/Tidal.svg?branch=1.0-dev)](https://travis-ci.org/tidalcycles/Tidal)
 =====
 
 Language for live coding of pattern
diff --git a/Sound/Tidal/Context.hs b/Sound/Tidal/Context.hs
--- a/Sound/Tidal/Context.hs
+++ b/Sound/Tidal/Context.hs
@@ -15,5 +15,7 @@
 import Sound.Tidal.SuperCollider as C
 import Sound.Tidal.Params as C
 import Sound.Tidal.Transition as C
+import Sound.Tidal.Version as C
 import qualified Sound.Tidal.Scales as Scales
 import qualified Sound.Tidal.Chords as Chords
+
diff --git a/Sound/Tidal/Dirt.hs b/Sound/Tidal/Dirt.hs
--- a/Sound/Tidal/Dirt.hs
+++ b/Sound/Tidal/Dirt.hs
@@ -171,8 +171,12 @@
 d1 $  slow 8 $ striate 128 $ sound "bev"
 @
 -}
-striate :: Int -> ParamPattern -> ParamPattern
-striate n p = cat $ map (\x -> off (fromIntegral x) p) [0 .. n-1]
+
+striate :: Pattern Int -> ParamPattern -> ParamPattern
+striate = temporalParam _striate
+
+_striate :: Int -> ParamPattern -> ParamPattern
+_striate n p = fastcat $ map (\x -> off (fromIntegral x) p) [0 .. n-1]
   where off i p = p
                   # begin (atom (fromIntegral i / fromIntegral n))
                   # end (atom (fromIntegral (i+1) / fromIntegral n))
@@ -193,13 +197,13 @@
 internally. This means that if you're using `striate` (or `striate'`)
 you probably shouldn't also specify `begin` or `end`. -}
 striate' :: Int -> Double -> ParamPattern -> ParamPattern
-striate' n f p = cat $ map (\x -> off (fromIntegral x) p) [0 .. n-1]
+striate' n f p = fastcat $ map (\x -> off (fromIntegral x) p) [0 .. n-1]
   where off i p = p # begin (atom (slot * i) :: Pattern Double) # end (atom ((slot * i) + f) :: Pattern Double)
         slot = (1 - f) / (fromIntegral n)
 
 {- | like `striate`, but with an offset to the begin and end values -}
 striateO :: Int -> Double -> ParamPattern -> ParamPattern
-striateO n o p = striate n p |+| begin (atom o :: Pattern Double) |+| end (atom o :: Pattern Double)
+striateO n o p = _striate n p |+| begin (atom o :: Pattern Double) |+| end (atom o :: Pattern Double)
 
 {- | Just like `striate`, but also loops each sample chunk a number of times specified in the second argument.
 The primed version is just like `striate'`, where the loop count is the third argument. For example:
@@ -211,10 +215,10 @@
 Like `striate`, these use the `begin` and `end` parameters internally, as well as the `loop` parameter for these versions.
 -}
 striateL :: Int -> Int -> ParamPattern -> ParamPattern
-striateL n l p = striate n p # loop (atom $ fromIntegral l)
+striateL n l p = _striate n p # loop (atom $ fromIntegral l)
 striateL' n f l p = striate' n f p # loop (atom $ fromIntegral l)
 
-metronome = slow 2 $ sound (p "[odx, [hh]*8]")
+metronome = _slow 2 $ sound (p "[odx, [hh]*8]")
 
 {-|
 Also degrades the current pattern and undegrades the next.
@@ -262,7 +266,7 @@
 xfadeIn :: Time -> Time -> [ParamPattern] -> ParamPattern
 xfadeIn _ _ [] = silence
 xfadeIn _ _ (p:[]) = p
-xfadeIn t now (p:p':_) = overlay (p |*| gain (now ~> (slow t envEqR))) (p' |*| gain (now ~> (slow t (envEq))))
+xfadeIn t now (p:p':_) = overlay (p |*| gain (now `rotR` (_slow t envEqR))) (p' |*| gain (now `rotR` (_slow t (envEq))))
 
 {- |
 Crossfade between old and new pattern over the next two cycles.
@@ -293,8 +297,12 @@
 d1 $ stut 4 0.5 (-0.2) $ sound "bd sn"
 @
 -}
-stut :: Integer -> Double -> Rational -> ParamPattern -> ParamPattern
-stut steps feedback time p = stack (p:(map (\x -> (((x%steps)*time) ~> (p |*| gain (pure $ scale (fromIntegral x))))) [1..(steps-1)]))
+
+stut :: Pattern Integer -> Pattern Double -> Pattern Rational -> ParamPattern -> ParamPattern
+stut n g t p = unwrap $ (\a b c -> _stut a b c p) <$> n <*> g <*> t
+
+_stut :: Integer -> Double -> Rational -> ParamPattern -> ParamPattern
+_stut steps feedback time p = stack (p:(map (\x -> (((x%steps)*time) `rotR` (p |*| gain (pure $ scale (fromIntegral x))))) [1..(steps-1)]))
   where scale x
           = ((+feedback) . (*(1-feedback)) . (/(fromIntegral steps)) . ((fromIntegral steps)-)) x
 
@@ -308,7 +316,7 @@
 -}
 stut' :: Integer -> Time -> (ParamPattern -> ParamPattern) -> ParamPattern -> ParamPattern
 stut' steps steptime f p | steps <= 0 = p
-                         | otherwise = overlay (f (steptime ~> stut' (steps-1) steptime f p)) p
+                         | otherwise = overlay (f (steptime `rotR` stut' (steps-1) steptime f p)) p
 
 {-| same as `anticipate` though it allows you to specify the number of cycles until dropping to the new pattern, e.g.:
 
@@ -318,7 +326,7 @@
 t1 (anticipateIn 4) $ sound "jvbass(5,8)"
 @-}
 anticipateIn :: Time -> Time -> [ParamPattern] -> ParamPattern
-anticipateIn t now = wash (spread' (stut 8 0.2) (now ~> (slow t $ (toRational . (1-)) <$> envL))) t now
+anticipateIn t now = wash (spread' (_stut 8 0.2) (now `rotR` (_slow t $ (toRational . (1-)) <$> envL))) t now
 
 {- | `anticipate` is an increasing comb filter.
 
diff --git a/Sound/Tidal/Params.hs b/Sound/Tidal/Params.hs
--- a/Sound/Tidal/Params.hs
+++ b/Sound/Tidal/Params.hs
@@ -6,10 +6,6 @@
 import Sound.Tidal.Utils
 import Control.Applicative
 
-make' :: (a -> Value) -> Param -> Pattern a -> ParamPattern
-make' toValue par p = fmap (\x -> Map.singleton par (defaultV x)) p
-  where defaultV a = toValue a
-
 -- | group multiple params into one
 grp :: [Param] -> Pattern String -> ParamPattern
 grp [] _ = silence
@@ -287,6 +283,10 @@
    , scr, sld, std, stt, sus, tdecay, vcf, vco, voi
       :: Pattern Double -> ParamPattern
 att = attack
+bpf = bandf
+bpf_p = bandf_p
+bpq = bandq
+bpq_p = bandq_p
 chdecay = clhatdecay
 ctf  = cutoff
 ctfg = cutoffegint
@@ -295,6 +295,10 @@
 det  = detune
 gat = gate
 hg = hatgrain
+hpf = hcutoff
+hpf_p = hcutoff_p
+hpq = hresonance
+hpq_p = hresonance_p
 lag = lagogo
 lbd = lkick
 lch = lclhat
@@ -307,6 +311,10 @@
 lht = lhitom
 llt = llotom
 loh = lophat
+lpf = cutoff
+lpf_p = cutoff_p
+lpq = resonance
+lpq_p = resonance_p
 lsn = lsnare
 ohdecay = ophatdecay
 pit1 = pitch1
diff --git a/Sound/Tidal/Parse.hs b/Sound/Tidal/Parse.hs
--- a/Sound/Tidal/Parse.hs
+++ b/Sound/Tidal/Parse.hs
@@ -24,7 +24,7 @@
 data TPat a
    = TPat_Atom a
    | TPat_Density Time (TPat a)
-      -- We keep this distinct from 'density' because of divide-by-zero:
+      -- We keep this distinct from '_density because of divide-by-zero:
    | TPat_Slow Time (TPat a)
    | TPat_Zoom Arc (TPat a)
    | TPat_DegradeBy Double (TPat a)
@@ -44,14 +44,14 @@
 toPat :: TPat a -> Pattern a
 toPat = \case
    TPat_Atom x -> atom x
-   TPat_Density t x -> density t $ toPat x
-   TPat_Slow t x -> slow t $ toPat x
+   TPat_Density t x -> _density t $ toPat x
+   TPat_Slow t x -> _slow t $ toPat x
    TPat_Zoom arc x -> zoom arc $ toPat x
-   TPat_DegradeBy amt x -> degradeBy amt $ toPat x
+   TPat_DegradeBy amt x -> _degradeBy amt $ toPat x
    TPat_Silence -> silence
-   TPat_Cat xs -> cat $ map toPat xs
+   TPat_Cat xs -> fastcat $ map toPat xs
    TPat_Overlay x0 x1 -> overlay (toPat x0) (toPat x1)
-   TPat_ShiftL t x -> t <~ toPat x
+   TPat_ShiftL t x -> t `rotL` toPat x
    TPat_pE n k s thing ->
       unwrap $ eoff <$> toPat n <*> toPat k <*> toPat s <*> pure (toPat thing)
    TPat_Foot -> error "Can't happen, feet (.'s) only used internally.."
@@ -304,13 +304,13 @@
                    return (a, b, c)
 
 eoff :: Int -> Int -> Integer -> Pattern a -> Pattern a
-eoff n k s p = ((s%(fromIntegral k)) <~) (e n k p)
+eoff n k s p = ((s%(fromIntegral k)) `rotL`) (e n k p)
    -- TPat_ShiftL (s%(fromIntegral k)) (TPat_E n k p)
 
 pReplicate :: TPat a -> Parser [TPat a]
 pReplicate thing =
   do extras <- many $ do char '!'
-                         -- if a number is given (without a space)
+                         -- if a number is given (without a space)slow 2 $ fast
                          -- replicate that number of times
                          n <- ((read <$> many1 digit) <|> return 2)
                          spaces
@@ -327,12 +327,19 @@
      return $ map (\x -> TPat_Zoom (x%n,(x+1)%n) thing) [0 .. (n-1)]
 
 pRatio :: Parser (Rational)
-pRatio = do n <- natural <?> "numerator"
-            d <- do oneOf "/%"
-                    natural <?> "denominator"
-                 <|>
-                 return 1
-            return $ n % d
+pRatio = do n <- natural
+            result <- do char '%'
+                         d <- natural
+                         return (n%d)
+                      <|>
+                      do char '.'
+                         d <- natural
+                         -- A hack, but not sure if doing this
+                         -- numerically would be any faster..
+                         return (toRational $ ((read $ show n ++ "." ++ show d)  :: Double))
+                      <|>
+                      return (n%1)
+            return result
 
 pRational :: Parser (TPat Rational)
 pRational = do r <- pRatio
diff --git a/Sound/Tidal/Pattern.hs b/Sound/Tidal/Pattern.hs
--- a/Sound/Tidal/Pattern.hs
+++ b/Sound/Tidal/Pattern.hs
@@ -1,25 +1,28 @@
-{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveDataTypeable, FlexibleContexts, CPP #-}
+{-# OPTIONS_GHC -Wall -fno-warn-orphans -fno-warn-name-shadowing #-}
 
 module Sound.Tidal.Pattern where
 
 import Control.Applicative
-import Data.Monoid
+-- import Data.Monoid
 import Data.Fixed
 import Data.List
 import Data.Maybe
 import Data.Ord
 import Data.Ratio
-import Debug.Trace
+-- import Debug.Trace
 import Data.Typeable
 import Data.Function
 import System.Random.Mersenne.Pure64
-import Data.Char
+-- import Data.Char
 import qualified Data.Text as T
 
 import Sound.Tidal.Time
 import Sound.Tidal.Utils
 import Sound.Tidal.Bjorklund
 
+import Text.Show.Functions ()
+
 -- | The pattern datatype, a function from a time @Arc@ to @Event@
 -- values. For discrete patterns, this returns the events which are
 -- active during that time. For continuous patterns, events with
@@ -27,40 +30,12 @@
 data Pattern a = Pattern {arc :: Arc -> [Event a]}
   deriving Typeable
 
--- | Admit the pattern datatype to the Num, Fractional and Floating classes,
--- to allow arithmetic on them, and for bare numbers to be automatically
--- converted into patterns of numbers
-instance Num a => Num (Pattern a) where
-      negate      = fmap negate
-      (+)         = liftA2 (+)
-      (*)         = liftA2 (*)
-      fromInteger = pure . fromInteger
-      abs         = fmap abs
-      signum      = fmap signum
-
-instance (Fractional a) => Fractional (Pattern a) where
-  fromRational = pure . fromRational
-  (/) = liftA2 (/)
+#define INSTANCE_Eq
+#define INSTANCE_Ord
+#define INSTANCE_Enum
 
-instance Floating a => Floating (Pattern a) where
-  pi = pure pi
-  exp = liftA (exp)
-  log = liftA (log)
-  sqrt = liftA (sqrt)
-  (**) = liftA2 (**)
-  logBase = liftA2 (logBase)
-  sin = liftA (sin)
-  cos = liftA (cos)
-  tan = liftA (tan)
-  asin = liftA (asin)
-  acos = liftA (acos)
-  atan = liftA (atan)
-  sinh = liftA (sinh)
-  cosh = liftA (cosh)
-  tanh = liftA (tanh)
-  asinh = liftA (asinh)
-  acosh = liftA (acosh)
-  atanh = liftA (atanh)
+#define APPLICATIVE Pattern
+#include "ApplicativeNumeric-inc.hs"
 
 -- | @show (p :: Pattern)@ returns a text string representing the
 -- event values active during the first cycle of the given pattern.
@@ -78,11 +53,14 @@
 
 -- | converts an event into human readable string, e.g. @("bd" 1/4 2/3)@
 showEvent :: (Show a) => Event a -> String
-showEvent (a, b, v) | a == b = concat["(",show v,
-                                      (' ':showArc a),
-                                      ")"
-                                     ]
-                    | otherwise = show v
+showEvent e@(_, b, v) = concat[on, show v, off,
+                               (' ':showArc b),
+                               "\n"
+                              ]
+  where on | hasOnset e = ""
+           | otherwise = ".."
+        off | hasOffset e = ""
+            | otherwise = ".."
 
 instance Functor Pattern where
   fmap f (Pattern a) = Pattern $ fmap (fmap (mapThd' f)) a
@@ -114,31 +92,15 @@
 
 instance Monad Pattern where
   return = pure
-  -- Pattern a -> (a -> Pattern b) -> Pattern b
-  -- Pattern Char -> (Char -> Pattern String) -> Pattern String
 
   p >>= f = unwrap (f <$> p)
-{-Pattern (\a -> concatMap
-                   (\((s,e), (s',e'), x) -> map (\ev -> ((s,e), (s',e'), thd' ev)) $
-                                            filter
-                                            (\(a', _, _) -> isIn a' s)
-                                            (arc (f x) (s,e))
-                   )
-                   (arc p a)
-             )
--}
--- join x = x >>= id
 
-
--- Take a pattern, and function from elements in the pattern to another pattern,
--- and then return that pattern
---bind :: Pattern a -> (a -> Pattern b) -> Pattern b
---bind p f =
-
--- this is actually join
 unwrap :: Pattern (Pattern a) -> Pattern a
-unwrap p = Pattern $ \a -> concatMap ((\p' -> arc p' a) . thd') (arc p a)
+unwrap p = Pattern $ \a -> concatMap (\(_, outerPart, p') -> catMaybes $ map (munge outerPart) $ arc p' a) (arc p a)
+  where munge a (whole,part,v) = do part' <- subArc a part
+                                    return (whole, part',v)
 
+
 -- | @atom@ is a synonym for @pure@.
 atom :: a -> Pattern a
 atom = pure
@@ -196,26 +158,25 @@
 -- first pattern, within a single cycle
 
 append :: Pattern a -> Pattern a -> Pattern a
-append a b = cat [a,b]
+append a b = fastcat [a,b]
 
 -- | @append'@ does the same as @append@, but over two cycles, so that
 -- the cycles alternate between the two patterns.
 append' :: Pattern a -> Pattern a -> Pattern a
-append' a b  = slow 2 $ cat [a,b]
+append' a b  = slowcat [a,b]
 
--- | @cat@ returns a new pattern which interlaces the cycles of the
+-- | @fastcat@ returns a new pattern which interlaces the cycles of the
 -- given patterns, within a single cycle. It's the equivalent of
 -- @append@, but with a list of patterns.
-cat :: [Pattern a] -> Pattern a
-cat ps = density (fromIntegral $ length ps) $ slowcat ps
-
+fastcat :: [Pattern a] -> Pattern a
+fastcat ps = _density (fromIntegral $ length ps) $ slowcat ps
 
 splitAtSam :: Pattern a -> Pattern a
 splitAtSam p =
   splitQueries $ Pattern $ \(s,e) -> mapSnds' (trimArc (sam s)) $ arc p (s,e)
   where trimArc s' (s,e) = (max (s') s, min (s'+1) e)
 
--- | @slowcat@ does the same as @cat@, but maintaining the duration of
+-- | @slowcat@ does the same as @fastcat@, but maintaining the duration of
 -- the original patterns. It is the equivalent of @append'@, but with
 -- a list of patterns.
 
@@ -231,61 +192,103 @@
                 offset = (fromIntegral $ r - ((r - n) `div` l)) :: Time
                 (s', e') = (s-offset, e-offset)
 
+-- | @cat@ is an alias of @slowcat@
+cat :: [Pattern a] -> Pattern a
+cat = slowcat
+
 -- | @listToPat@ turns the given list of values to a Pattern, which
 -- cycles through the list.
 listToPat :: [a] -> Pattern a
-listToPat = cat . map atom
+listToPat = fastcat . map atom
 
 -- | @maybeListToPat@ is similar to @listToPat@, but allows values to
 -- be optional using the @Maybe@ type, so that @Nothing@ results in
 -- gaps in the pattern.
 maybeListToPat :: [Maybe a] -> Pattern a
-maybeListToPat = cat . map f
+maybeListToPat = fastcat . map f
   where f Nothing = silence
         f (Just x) = atom x
 
 -- | @run@ @n@ returns a pattern representing a cycle of numbers from @0@ to @n-1@.
-run n = listToPat [0 .. n-1]
-scan n = cat $ map run [1 .. n]
+run :: (Enum a, Num a) => Pattern a -> Pattern a
+run tp =  tp >>= _run
 
--- | @density@ returns the given pattern with density increased by the
--- given @Time@ factor. Therefore @density 2 p@ will return a pattern
--- that is twice as fast, and @density (1/3) p@ will return one three
--- times as slow.
-density :: Time -> Pattern a -> Pattern a
-density r p = withResultTime (/ r) $ withQueryTime (* r) p
+_run :: (Enum a, Num a) => a -> Pattern a
+_run n = listToPat [0 .. n-1]
 
-density' :: Pattern Time -> Pattern a -> Pattern a
-density' tp p = unwrap $ (\tv -> density tv p) <$> tp
+scan :: (Enum a, Num a) => Pattern a -> Pattern a
+scan tp =  tp >>= _scan
 
--- | @densityGap@ is similar to @density@ but maintains its cyclic
--- alignment. For example, @densityGap 2 p@ would squash the events in
+_scan :: (Enum a, Num a) => a -> Pattern a
+_scan n = slowcat $ map _run [1 .. n]
+
+temporalParam :: (a -> Pattern b -> Pattern c) -> (Pattern a -> Pattern b -> Pattern c)
+temporalParam f tv p = unwrap $ (\v -> f v p) <$> tv
+
+temporalParam' :: (a -> Pattern b -> Pattern c) -> (Pattern a -> Pattern b -> Pattern c)
+temporalParam' f tv p = unwrap' $ (\v -> f v p) <$> tv
+
+-- | @fast@ (also known as @density@) returns the given pattern with speed
+-- (or density) increased by the given @Time@ factor. Therefore @fast 2 p@
+-- will return a pattern that is twice as fast, and @fast (1/3) p@
+-- will return one three times as slow.
+fast :: Pattern Time -> Pattern a -> Pattern a
+fast = temporalParam _density
+
+fast' :: Pattern Time -> Pattern a -> Pattern a
+fast' = temporalParam' _density
+
+-- | @density@ is an alias of @fast@. @fast@ is quicker to type, but
+-- @density@ is its old name so is used in a lot of examples.
+density :: Pattern Time -> Pattern a -> Pattern a
+density = fast
+
+_density :: Time -> Pattern a -> Pattern a
+_density r p = withResultTime (/ r) $ withQueryTime (* r) p
+
+-- | @fastGap@ (also known as @densityGap@ is similar to @fast@ but maintains its cyclic
+-- alignment. For example, @fastGap 2 p@ would squash the events in
 -- pattern @p@ into the first half of each cycle (and the second
 -- halves would be empty).
+fastGap :: Time -> Pattern a -> Pattern a
+fastGap 0 _ = silence
+fastGap r p = splitQueries $ withResultArc (\(s,e) -> (sam s + ((s - sam s)/r), (sam s + ((e - sam s)/r)))) $ Pattern (\a -> arc p $ mapArc (\t -> sam t + (min 1 (r * cyclePos t))) a)
+
 densityGap :: Time -> Pattern a -> Pattern a
-densityGap 0 _ = silence
-densityGap r p = splitQueries $ withResultArc (\(s,e) -> (sam s + ((s - sam s)/r), (sam s + ((e - sam s)/r)))) $ Pattern (\a -> arc p $ mapArc (\t -> sam t + (min 1 (r * cyclePos t))) a)
+densityGap = fastGap
 
--- | @slow@ does the opposite of @density@, i.e. @slow 2 p@ will
--- return a pattern that is half the speed.
-slow :: Time -> Pattern a -> Pattern a
-slow 0 = id
-slow t = density (1/t)
+-- | @slow@ does the opposite of @fast@, i.e. @slow 2 p@ will return a
+-- pattern that is half the speed.
+slow :: Pattern Time -> Pattern a -> Pattern a
+slow = temporalParam _slow
 
-slow' tp p = density' (1/tp) p
+sparsity :: Pattern Time -> Pattern a -> Pattern a
+sparsity = slow
 
+slow' :: Pattern Time -> Pattern a -> Pattern a
+slow' = temporalParam' _slow
+
+_slow :: Time -> Pattern a -> Pattern a
+_slow t p = _density (1/t) p
+
 -- | The @<~@ operator shifts (or rotates) a pattern to the left (or
 -- counter-clockwise) by the given @Time@ value. For example
 -- @(1%16) <~ p@ will return a pattern with all the events moved
 -- one 16th of a cycle to the left.
-(<~) :: Time -> Pattern a -> Pattern a
-(<~) t p = withResultTime (subtract t) $ withQueryTime (+ t) p
+rotL :: Time -> Pattern a -> Pattern a
+rotL t p = withResultTime (subtract t) $ withQueryTime (+ t) p
 
+(<~) :: Pattern Time -> Pattern a -> Pattern a
+(<~) = temporalParam rotL
+
 -- | The @~>@ operator does the same as @<~@ but shifts events to the
 -- right (or clockwise) rather than to the left.
-(~>) :: Time -> Pattern a -> Pattern a
-(~>) = (<~) . (0-)
+rotR :: Time -> Pattern a -> Pattern a
+rotR = (rotL) . (0-)
 
+(~>) :: Pattern Time -> Pattern a -> Pattern a
+(~>) = temporalParam rotR
+
 {- | (The above means that `brak` is a function from patterns of any type,
 to a pattern of the same type.)
 
@@ -298,7 +301,7 @@
 @
 -}
 brak :: Pattern a -> Pattern a
-brak = when ((== 1) . (`mod` 2)) (((1%4) ~>) . (\x -> cat [x, silence]))
+brak = when ((== 1) . (`mod` 2)) (((1%4) `rotR`) . (\x -> fastcat [x, silence]))
 
 {- | Divides a pattern into a given number of subdivisions, plays the subdivisions
 in order, but increments the starting subdivision each cycle. The pattern
@@ -322,14 +325,20 @@
 There is also `iter'`, which shifts the pattern in the opposite direction.
 
 -}
-iter :: Int -> Pattern a -> Pattern a
-iter n p = slowcat $ map (\i -> ((fromIntegral i)%(fromIntegral n)) <~ p) [0 .. (n-1)]
+iter :: Pattern Int -> Pattern c -> Pattern c
+iter = temporalParam _iter
 
+_iter :: Int -> Pattern a -> Pattern a
+_iter n p = slowcat $ map (\i -> ((fromIntegral i)%(fromIntegral n)) `rotL` p) [0 .. (n-1)]
+
 -- | @iter'@ is the same as @iter@, but decrements the starting
 -- subdivision instead of incrementing it.
-iter' :: Int -> Pattern a -> Pattern a
-iter' n p = slowcat $ map (\i -> ((fromIntegral i)%(fromIntegral n)) ~> p) [0 .. (n-1)]
+iter' :: Pattern Int -> Pattern c -> Pattern c
+iter' = temporalParam _iter'
 
+_iter' :: Int -> Pattern a -> Pattern a
+_iter' n p = slowcat $ map (\i -> ((fromIntegral i)%(fromIntegral n)) `rotR` p) [0 .. (n-1)]
+
 -- | @rev p@ returns @p@ with the event positions in each cycle
 -- reversed (or mirrored).
 rev :: Pattern a -> Pattern a
@@ -337,6 +346,7 @@
 
 -- | @palindrome p@ applies @rev@ to @p@ every other cycle, so that
 -- the pattern alternates between forwards and backwards.
+palindrome :: Pattern a -> Pattern a
 palindrome p = append' p (rev p)
 
 {-|
@@ -381,14 +391,17 @@
 @
 -}
 seqP :: [(Time, Time, Pattern a)] -> Pattern a
-seqP ps = stack $ map (\(s, e, p) -> playFor s e ((sam s) ~> p)) ps
+seqP ps = stack $ map (\(s, e, p) -> playFor s e ((sam s) `rotR` p)) ps
 
 -- | @every n f p@ applies the function @f@ to @p@, but only affects
 -- every @n@ cycles.
-every :: Int -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
-every 0 _ p = p
-every n f p = when ((== 0) . (`mod` n)) f p
+every :: Pattern Int -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
+every tp f p = tp >>= \t -> _every t f p
 
+_every :: Int -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
+_every 0 _ p = p
+_every n f p = when ((== 0) . (`mod` n)) f p
+
 -- | @every n o f'@ is like @every n f@ with an offset of @o@ cycles
 every' :: Int -> Int -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
 every' n o f = when ((== o) . (`mod` n)) f
@@ -396,7 +409,7 @@
 -- | @foldEvery ns f p@ applies the function @f@ to @p@, and is applied for
 -- each cycle in @ns@.
 foldEvery :: [Int] -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
-foldEvery ns f p = foldr ($) p (map (\x -> every x f) ns)
+foldEvery ns f p = foldr ($) p (map (\x -> _every x f) ns)
 
 -- | @sig f@ takes a function from time to values, and turns it into a
 -- @Pattern@.
@@ -406,90 +419,89 @@
                  | otherwise = [((s,e), (s,e), f s)]
 
 -- | @sinewave@ returns a @Pattern@ of continuous @Double@ values following a
--- sinewave with frequency of one cycle, and amplitude from -1 to 1.
+-- sinewave with frequency of one cycle, and amplitude from 0 to 1.
 sinewave :: Pattern Double
-sinewave = sig $ \t -> sin $ pi * 2 * (fromRational t)
+sinewave = sig $ \t -> ((sin $ pi * 2 * (fromRational t)) + 1) / 2
+
 -- | @sine@ is a synonym for @sinewave@.
+sine :: Pattern Double
 sine = sinewave
+
 -- | @sinerat@ is equivalent to @sinewave@ for @Rational@ values,
 -- suitable for use as @Time@ offsets.
+sinerat :: Pattern Rational
 sinerat = fmap toRational sine
+
 -- | @ratsine@ is a synonym for @sinerat@.
+ratsine :: Pattern Rational
 ratsine = sinerat
 
--- | @sinewave1@ is equivalent to @sinewave@, but with amplitude from 0 to 1.
-sinewave1 :: Pattern Double
-sinewave1 = fmap ((/ 2) . (+ 1)) sinewave
-
--- | @sine1@ is a synonym for @sinewave1@.
-sine1 = sinewave1
-
--- | @sinerat1@ is equivalent to @sinerat@, but with amplitude from 0 to 1.
-sinerat1 = fmap toRational sine1
-
--- | @sineAmp1 d@ returns @sinewave1@ with its amplitude offset by @d@.
-sineAmp1 :: Double -> Pattern Double
-sineAmp1 offset = (+ offset) <$> sinewave1
+-- | @sineAmp d@ returns @sinewave@ with its amplitude offset by @d@.
+-- Deprecated, as these days you can simply do e.g. (sine + 0.5)
+sineAmp :: Double -> Pattern Double
+sineAmp offset = (+ offset) <$> sinewave1
 
 -- | @sawwave@ is the equivalent of @sinewave@ for (ascending) sawtooth waves.
 sawwave :: Pattern Double
-sawwave = ((subtract 1) . (* 2)) <$> sawwave1
+sawwave = sig $ \t -> mod' (fromRational t) 1
 
 -- | @saw@ is a synonym for @sawwave@.
+saw :: Pattern Double
 saw = sawwave
 
 -- | @sawrat@ is the same as @sawwave@ but returns @Rational@ values
 -- suitable for use as @Time@ offsets.
+sawrat :: Pattern Rational
 sawrat = fmap toRational saw
 
--- | @sawwave1@ is the equivalent of @sinewave1@ for (ascending) sawtooth waves.
-sawwave1 :: Pattern Double
-sawwave1 = sig $ \t -> mod' (fromRational t) 1
-
--- | @saw1@ is a synonym for @sawwave1@.
-saw1 = sawwave1
-
--- | @sawrat1@ is the same as @sawwave1@ but returns @Rational@ values
--- suitable for use as @Time@ offsets.
-sawrat1 = fmap toRational saw1
-
 -- | @triwave@ is the equivalent of @sinewave@ for triangular waves.
 triwave :: Pattern Double
-triwave = ((subtract 1) . (* 2)) <$> triwave1
+triwave = append sawwave1 (rev sawwave1)
 
 -- | @tri@ is a synonym for @triwave@.
+tri :: Pattern Double
 tri = triwave
 
 -- | @trirat@ is the same as @triwave@ but returns @Rational@ values
 -- suitable for use as @Time@ offsets.
+trirat :: Pattern Rational
 trirat = fmap toRational tri
 
--- | @triwave1@ is the equivalent of @sinewave1@ for triangular waves.
-triwave1 :: Pattern Double
-triwave1 = append sawwave1 (rev sawwave1)
-
--- | @tri1@ is a synonym for @triwave1@.
-tri1 = triwave1
-
--- | @trirat1@ is the same as @triwave1@ but returns @Rational@ values
--- suitable for use as @Time@ offsets.
-trirat1 = fmap toRational tri1
-
--- | @squarewave1@ is the equivalent of @sinewave1@ for square waves.
-squarewave1 :: Pattern Double
-squarewave1 = sig $
-              \t -> fromIntegral $ floor $ (mod' (fromRational t) 1) * 2
-
--- | @square1@ is a synonym for @squarewave1@.
-square1 = squarewave1
-
--- | @squarewave@ is the equivalent of @sinewave@ for square waves.
+-- | @squarewave1@ is the equivalent of @sinewave@ for square waves.
 squarewave :: Pattern Double
-squarewave = ((subtract 1) . (* 2)) <$> squarewave1
+squarewave = sig $
+             \t -> fromIntegral $ ((floor $ (mod' (fromRational t :: Double) 1) * 2) :: Integer)
 
 -- | @square@ is a synonym for @squarewave@.
+square :: Pattern Double
 square = squarewave
 
+-- deprecated..
+sinewave1 :: Pattern Double
+sinewave1 = sinewave
+sine1 :: Pattern Double
+sine1 = sinewave
+sinerat1 :: Pattern Rational
+sinerat1 = sinerat
+sineAmp1 :: Double -> Pattern Double
+sineAmp1 = sineAmp
+sawwave1 :: Pattern Double
+sawwave1 = sawwave
+saw1 :: Pattern Double
+saw1 = sawwave
+sawrat1 :: Pattern Rational
+sawrat1 = sawrat
+triwave1 :: Pattern Double
+triwave1 = triwave
+tri1 :: Pattern Double
+tri1 = triwave
+trirat1 :: Pattern Rational
+trirat1 = trirat
+squarewave1 :: Pattern Double
+squarewave1 = squarewave
+square1 :: Pattern Double
+square1 = square
+
 -- | @envL@ is a @Pattern@ of continuous @Double@ values, representing
 -- a linear interpolation between 0 and 1 during the first cycle, then
 -- staying constant at 1 for all following cycles. Possibly only
@@ -505,25 +517,27 @@
 -- 'Equal power' for gain-based transitions
 envEq :: Pattern Double
 envEq = sig $ \t -> sqrt (sin (pi/2 * (max 0 $ min (fromRational (1-t)) 1)))
+
 -- Equal power reversed
+envEqR :: Pattern Double
 envEqR = sig $ \t -> sqrt (cos (pi/2 * (max 0 $ min (fromRational (1-t)) 1)))
 
 fadeOut :: Time -> Pattern a -> Pattern a
-fadeOut n = spread' (degradeBy) (slow n $ envL)
+fadeOut n = spread' (_degradeBy) (_slow n $ envL)
 
 -- Alternate versions where you can provide the time from which the fade starts
 fadeOut' :: Time -> Time -> Pattern a -> Pattern a
-fadeOut' from dur p = spread' (degradeBy) (from ~> slow dur envL) p
+fadeOut' from dur p = spread' (_degradeBy) (from `rotR` _slow dur envL) p
 
 -- The 1 <~ is so fade ins and outs have different degredations
 fadeIn' :: Time -> Time -> Pattern a -> Pattern a
-fadeIn' from dur p = spread' (\n p -> 1 <~ degradeBy n p) (from ~> slow dur ((1-) <$> envL)) p
+fadeIn' from dur p = spread' (\n p -> 1 `rotL` _degradeBy n p) (from `rotR` _slow dur ((1-) <$> envL)) p
 
 fadeIn :: Time -> Pattern a -> Pattern a
-fadeIn n = spread' (degradeBy) (slow n $ (1-) <$> envL)
+fadeIn n = spread' (_degradeBy) (_slow n $ (1-) <$> envL)
 
 {- | (The above is difficult to describe, if you don't understand Haskell,
-just read the description and examples..)
+just ignore it and read the below..)
 
 The `spread` function allows you to take a pattern transformation
 which takes a parameter, such as `slow`, and provide several
@@ -577,6 +591,7 @@
 spread :: (a -> t -> Pattern b) -> [a] -> t -> Pattern b
 spread f xs p = slowcat $ map (\x -> f x p) xs
 
+slowspread :: (a -> t -> Pattern b) -> [a] -> t -> Pattern b
 slowspread = spread
 
 {- | @fastspread@ works the same as @spread@, but the result is squashed into a single cycle. If you gave four values to @spread@, then the result would seem to speed up by a factor of four. Compare these two:
@@ -588,7 +603,7 @@
 There is also @slowspread@, which is an alias of @spread@.
 -}
 fastspread :: (a -> t -> Pattern b) -> [a] -> t -> Pattern b
-fastspread f xs p = cat $ map (\x -> f x p) xs
+fastspread f xs p = fastcat $ map (\x -> f x p) xs
 
 {- | There's a version of this function, `spread'` (pronounced "spread prime"), which takes a *pattern* of parameters, instead of a list:
 
@@ -614,11 +629,16 @@
 spreadChoose :: (t -> t1 -> Pattern b) -> [t] -> t1 -> Pattern b
 spreadChoose f vs p = do v <- discretise 1 (choose vs)
                          f v p
+
+spreadr :: (t -> t1 -> Pattern b) -> [t] -> t1 -> Pattern b
 spreadr = spreadChoose
 
 filterValues :: (a -> Bool) -> Pattern a -> Pattern a
 filterValues f (Pattern x) = Pattern $ (filter (f . thd')) . x
 
+filterJust :: Pattern (Maybe a) -> Pattern a
+filterJust p = fromJust <$> (filterValues (isJust) p)
+
 -- Filter out events that have had their onsets cut off
 filterOnsets :: Pattern a -> Pattern a
 filterOnsets (Pattern f) =
@@ -630,6 +650,7 @@
 filterStartInRange (Pattern f) =
   Pattern $ \(s,e) -> filter ((isIn (s,e)) . eventOnset) $ f (s,e)
 
+filterOnsetsInRange :: Pattern a -> Pattern a
 filterOnsetsInRange = filterOnsets . filterStartInRange
 
 -- Samples some events from a pattern, returning a list of onsets
@@ -656,6 +677,7 @@
 groupByTime :: [Event a] -> [Event [a]]
 groupByTime es = map mrg $ groupBy ((==) `on` snd') $ sortBy (compare `on` snd') es
   where mrg es@((a, a', _):_) = (a, a', map thd' es)
+        mrg _ = error "groupByTime"
 
 
 {-| Decide whether to apply one or another function depending on the result of a test function that is passed the current cycle as a number.
@@ -709,17 +731,18 @@
 rand :: Pattern Double
 rand = Pattern $ \a -> [(a, a, timeToRand $ (midPoint a))]
 
+timeToRand :: RealFrac r => r -> Double
 timeToRand t = fst $ randomDouble $ pureMT $ floor $ (*1000000) t
 
-{- | Just like `rand` but for integers, `irand n` generates a pattern of (pseudo-)random integers between `0` to `n-1` inclusive. Notably used to pick a random
+{- | Just like `rand` but for whole numbers, `irand n` generates a pattern of (pseudo-) random whole numbers between `0` to `n-1` inclusive. Notably used to pick a random
 samples from a folder:
 
 @
-d1 $ sound (samples "drum*4" (irand 5))
+d1 $ n (irand 5) # sound "drum"
 @
 -}
-irand :: Int -> Pattern Int
-irand i = (floor . (* (fromIntegral i))) <$> rand
+irand :: Num a => Int -> Pattern a
+irand i = (fromIntegral . (floor :: Double -> Int) . (* (fromIntegral i))) <$> rand
 
 {- | Randomly picks an element from the given list
 
@@ -743,18 +766,23 @@
 @
 
 -}
-degradeBy :: Double -> Pattern a -> Pattern a
-degradeBy x p = unMaybe $ (\a f -> toMaybe (f > x) a) <$> p <*> rand
-    where toMaybe False _ = Nothing
-          toMaybe True a  = Just a
-          unMaybe = (fromJust <$>) . filterValues isJust
 
-unDegradeBy :: Double -> Pattern a -> Pattern a
-unDegradeBy x p = unMaybe $ (\a f -> toMaybe (f <= x) a) <$> p <*> rand
-    where toMaybe False _ = Nothing
-          toMaybe True a  = Just a
-          unMaybe = (fromJust <$>) . filterValues isJust
+degradeBy :: Pattern Double -> Pattern a -> Pattern a
+degradeBy = temporalParam _degradeBy
 
+_degradeBy :: Double -> Pattern a -> Pattern a
+_degradeBy x p = fmap fst $ filterValues ((> x) . snd) $ (,) <$> p <*> rand
+
+unDegradeBy :: Pattern Double -> Pattern a -> Pattern a
+unDegradeBy = temporalParam _unDegradeBy
+
+_unDegradeBy :: Double -> Pattern a -> Pattern a
+_unDegradeBy x p = fmap fst $ filterValues ((<= x) . snd) $ (,) <$> p <*> rand
+
+degradeOverBy :: Int -> Pattern Double -> Pattern a -> Pattern a
+degradeOverBy i tx p = unwrap $ (\x -> (fmap fst $ filterValues ((> x) . snd) $ (,) <$> p <*> repeatCycles i rand)) <$> (slow (fromIntegral i) tx)
+
+
 {- | Use @sometimesBy@ to apply a given function "sometimes". For example, the
 following code results in `density 2` being applied about 25% of the time:
 
@@ -773,28 +801,44 @@
 @
 -}
 sometimesBy :: Double -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
-sometimesBy x f p = overlay (degradeBy x p) (f $ unDegradeBy x p)
+sometimesBy x f p = overlay (_degradeBy x p) (f $ _unDegradeBy x p)
 
 -- | @sometimes@ is an alias for sometimesBy 0.5.
+sometimes :: (Pattern a -> Pattern a) -> Pattern a -> Pattern a
 sometimes = sometimesBy 0.5
+
 -- | @often@ is an alias for sometimesBy 0.75.
+often :: (Pattern a -> Pattern a) -> Pattern a -> Pattern a
 often = sometimesBy 0.75
+
 -- | @rarely@ is an alias for sometimesBy 0.25.
+rarely :: (Pattern a -> Pattern a) -> Pattern a -> Pattern a
 rarely = sometimesBy 0.25
+
 -- | @almostNever@ is an alias for sometimesBy 0.1
+almostNever :: (Pattern a -> Pattern a) -> Pattern a -> Pattern a
 almostNever = sometimesBy 0.1
+
 -- | @almostAlways@ is an alias for sometimesBy 0.9
+almostAlways :: (Pattern a -> Pattern a) -> Pattern a -> Pattern a
 almostAlways = sometimesBy 0.9
+
+never :: (Pattern a -> Pattern a) -> Pattern a -> Pattern a
 never = flip const
+
+always :: (Pattern a -> Pattern a) -> Pattern a -> Pattern a
 always = id
 
 {- | @someCyclesBy@ is a cycle-by-cycle version of @sometimesBy@. It has a
 `someCycles = someCyclesBy 0.5` alias -}
+someCyclesBy :: Double -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
 someCyclesBy x = when (test x)
-  where test x c = (timeToRand $ fromIntegral c) < x
+  where test x c = (timeToRand (fromIntegral c :: Double)) < x
 
+somecyclesBy :: Double -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
 somecyclesBy = someCyclesBy
 
+someCycles :: (Pattern a -> Pattern a) -> Pattern a -> Pattern a
 someCycles = someCyclesBy 0.5
 
 {- | `degrade` randomly removes events from a pattern 50% of the time:
@@ -819,13 +863,13 @@
 @
 -}
 degrade :: Pattern a -> Pattern a
-degrade = degradeBy 0.5
+degrade = _degradeBy 0.5
 
 -- | @wedge t p p'@ combines patterns @p@ and @p'@ by squashing the
 -- @p@ into the portion of each cycle given by @t@, and @p'@ into the
 -- remainer of each cycle.
 wedge :: Time -> Pattern a -> Pattern a -> Pattern a
-wedge t p p' = overlay (densityGap (1/t) p) (t ~> densityGap (1/(1-t)) p')
+wedge t p p' = overlay (densityGap (1/t) p) (t `rotR` densityGap (1/(1-t)) p')
 
 {- | @whenmod@ has a similar form and behavior to `every`, but requires an
 additional number. Applies the function to the pattern, when the
@@ -856,6 +900,7 @@
 @
 
 -}
+superimpose :: (Pattern a -> Pattern a) -> Pattern a -> Pattern a
 superimpose f p = stack [p, f p]
 
 -- | @splitQueries p@ wraps `p` to ensure that it does not get
@@ -873,9 +918,12 @@
 d1 $ trunc 0.75 $ sound "bd sn*2 cp hh*4 arpy bd*2 cp bd*2"
 @
 -}
-trunc :: Time -> Pattern a -> Pattern a
-trunc t = compress (0,t) . zoom (0,t)
+trunc :: Pattern Time -> Pattern a -> Pattern a
+trunc = temporalParam _trunc
 
+_trunc :: Time -> Pattern a -> Pattern a
+_trunc t = compress (0,t) . zoom (0,t)
+
 {- | Plays a portion of a pattern, specified by a beginning and end arc of time.
 The new resulting pattern is played over the time period of the original pattern:
 
@@ -890,12 +938,12 @@
 @
 -}
 zoom :: Arc -> Pattern a -> Pattern a
-zoom a@(s,e) p = splitQueries $ withResultArc (mapCycle ((/d) . (subtract s))) $ withQueryArc (mapCycle ((+s) . (*d))) p
+zoom (s,e) p = splitQueries $ withResultArc (mapCycle ((/d) . (subtract s))) $ withQueryArc (mapCycle ((+s) . (*d))) p
      where d = e-s
 
 compress :: Arc -> Pattern a -> Pattern a
-compress a@(s,e) p | s >= e = silence
-                   | otherwise = s ~> densityGap (1/(e-s)) p
+compress (s,e) p | s >= e = silence
+                 | otherwise = s `rotR` densityGap (1/(e-s)) p
 
 sliceArc :: Arc -> Pattern a -> Pattern a
 sliceArc a@(s,e) p | s >= e = silence
@@ -921,6 +969,7 @@
                            sliceArc (e,1) p
                           ]
 
+revArc :: Arc -> Pattern a -> Pattern a
 revArc a = within a rev
 
 {- | You can use the @e@ function to apply a Euclidean algorithm over a
@@ -971,7 +1020,7 @@
 e n k p = (flip const) <$> (filterValues (== True) $ listToPat $ bjorklund (n,k)) <*> p
 
 e' :: Int -> Int -> Pattern a -> Pattern a
-e' n k p = cat $ map (\x -> if x then p else silence) (bjorklund (n,k))
+e' n k p = fastcat $ map (\x -> if x then p else silence) (bjorklund (n,k))
 
 
 index :: Real b => b -> Pattern b -> Pattern c -> Pattern c
@@ -987,9 +1036,9 @@
     values = fmap thd' . sortBy ecompare $ arc valuePattern (0, vlen)
     cycles = blen * (fromIntegral $ lcm (length beats) (length values) `div` (length beats))
   in
-    slow cycles $ stack $ zipWith
-    (\( _, (start, end), v') v -> (start ~>) $ densityGap (1 / (end - start)) $ pure (f v' v))
-    (sortBy ecompare $ arc (density cycles $ beatPattern) (0, blen))
+    _slow cycles $ stack $ zipWith
+    (\( _, (start, end), v') v -> (start `rotR`) $ densityGap (1 / (end - start)) $ pure (f v' v))
+    (sortBy ecompare $ arc (_density cycles $ beatPattern) (0, blen))
     (drop (rot `mod` length values) $ cycle values)
 
 -- | @prr rot (blen, vlen) beatPattern valuePattern@: pattern rotate/replace.
@@ -1024,6 +1073,7 @@
 preplace = preplaceWith $ flip const
 
 -- | @prep@ is an alias for preplace.
+prep :: (Time, Time) -> Pattern String -> Pattern b -> Pattern b
 prep = preplace
 
 preplace1 :: Pattern String -> Pattern b -> Pattern b
@@ -1032,11 +1082,13 @@
 preplaceWith :: (a -> b -> c) -> (Time, Time) -> Pattern a -> Pattern b -> Pattern c
 preplaceWith f (blen, plen) = prrw f 0 (blen, plen)
 
+prw :: (a -> b -> c) -> (Time, Time) -> Pattern a -> Pattern b -> Pattern c
 prw = preplaceWith
 
 preplaceWith1 :: (a -> b -> c) -> Pattern a -> Pattern b -> Pattern c
 preplaceWith1 f = prrw f 0 (1, 1)
 
+prw1 :: (a -> b -> c) -> Pattern a -> Pattern b -> Pattern c
 prw1 = preplaceWith1
 
 (<~>) :: Pattern String -> Pattern b -> Pattern b
@@ -1048,7 +1100,10 @@
 protate :: Time -> Int -> Pattern a -> Pattern a
 protate len rot p = prrw (flip const) rot (len, len) p p
 
+prot :: Time -> Int -> Pattern a -> Pattern a
 prot = protate
+
+prot1 :: Int -> Pattern a -> Pattern a
 prot1 = protate 1
 
 {-| The @<<~@ operator rotates a unit pattern to the left, similar to @<~@,
@@ -1074,13 +1129,16 @@
 -- | @discretise n p@: 'samples' the pattern @p@ at a rate of @n@
 -- events per cycle. Useful for turning a continuous pattern into a
 -- discrete one.
-discretise :: Time -> Pattern a -> Pattern a
-discretise n p = density n $ (atom (id)) <*> p
+discretise :: Pattern Time -> Pattern a -> Pattern a
+discretise n p = (density n $ atom (id)) <*> p
 
+discretise' :: Time -> Pattern a -> Pattern a
+discretise' n p = (_density n $ atom (id)) <*> p
+
 -- | @randcat ps@: does a @slowcat@ on the list of patterns @ps@ but
 -- randomises the order in which they are played.
 randcat :: [Pattern a] -> Pattern a
-randcat ps = spread' (<~) (discretise 1 $ ((%1) . fromIntegral) <$> irand (length ps - 1)) (slowcat ps)
+randcat ps = spread' (rotL) (discretise 1 $ ((%1) . fromIntegral) <$> (irand (length ps - 1) :: Pattern Int)) (slowcat ps)
 
 -- @fromNote p@: converts a pattern of human-readable pitch names
 -- into pitch numbers. For example, @"cs2"@ will be parsed as C Sharp
@@ -1135,7 +1193,7 @@
 permstep steps things p = unwrap $ (\n -> listToPat $ concatMap (\x -> replicate (fst x) (snd x)) $ zip (ps !! (floor (n * (fromIntegral $ (length ps - 1))))) things) <$> (discretise 1 p)
       where ps = permsort (length things) steps
             deviance avg xs = sum $ map (abs . (avg-) . fromIntegral) xs
-            permsort n total = map fst $ sortBy (comparing snd) $ map (\x -> (x,deviance (fromIntegral total/ fromIntegral n) x)) $ perms n total
+            permsort n total = map fst $ sortBy (comparing snd) $ map (\x -> (x,deviance (fromIntegral total / (fromIntegral n :: Double)) x)) $ perms n total
             perms 0 _ = []
             perms 1 n = [[n]]
             perms n total = concatMap (\x -> map (x:) $ perms (n-1) (total-x)) [1 .. (total-(n-1))]
@@ -1244,37 +1302,46 @@
 which uses `chop` to break a single sample into individual pieces, which `fit'` then puts into a list (using the `run 4` pattern) and reassembles according to the complicated integer pattern.
 
 -}
+fit' :: Pattern Time -> Int -> Pattern Int -> Pattern Int -> Pattern a -> Pattern a
 fit' cyc n from to p = unwrap' $ fit n (mapMasks n from' p') to
   where mapMasks n from p = [stretch $ mask (filterValues (== i) from) p
                              | i <- [0..n-1]]
         p' = density cyc $ p
         from' = density cyc $ from
 
-{-| @runWith n f p@ treats the given pattern @p@ as having @n@ sections, and applies the function @f@ to one of those sections per cycle, running from left to right.
+{-| @chunk n f p@ treats the given pattern @p@ as having @n@ chunks, and applies the function @f@ to one of those sections per cycle, running from left to right.
 
 @
-d1 $ runWith 4 (density 4) $ sound "cp sn arpy [mt lt]"
+d1 $ chunk 4 (density 4) $ sound "cp sn arpy [mt lt]"
 @
 -}
-runWith :: Integral a => a -> (Pattern b -> Pattern b) -> Pattern b -> Pattern b
-runWith n f p = do i <- slow (toRational n) $ run (fromIntegral n)
-                   within (i%(fromIntegral n),(i+)1%(fromIntegral n)) f p
+chunk :: Integral a => a -> (Pattern b -> Pattern b) -> Pattern b -> Pattern b
+chunk n f p = do i <- _slow (toRational n) $ run (fromIntegral n)
+                 within (i%(fromIntegral n),(i+)1%(fromIntegral n)) f p
 
+-- deprecated (renamed to chunk)
+runWith :: Integral a => a -> (Pattern b -> Pattern b) -> Pattern b -> Pattern b
+runWith = chunk
 
-{-| @runWith'@ works much the same as `runWith`, but runs from right to left.
+{-| @chunk'@ works much the same as `chunk`, but runs from right to left.
 -}
+chunk' :: Integral a => a -> (Pattern b -> Pattern b) -> Pattern b -> Pattern b
+chunk' n f p = do i <- _slow (toRational n) $ rev $ run (fromIntegral n)
+                  within (i%(fromIntegral n),(i+)1%(fromIntegral n)) f p
+
+-- deprecated (renamed to chunk')
 runWith' :: Integral a => a -> (Pattern b -> Pattern b) -> Pattern b -> Pattern b
-runWith' n f p = do i <- slow (toRational n) $ rev $ run (fromIntegral n)
-                    within (i%(fromIntegral n),(i+)1%(fromIntegral n)) f p
+runWith' = chunk'
 
 inside :: Time -> (Pattern a1 -> Pattern a) -> Pattern a1 -> Pattern a
-inside n f p = density n $ f (slow n p)
+inside n f p = _density n $ f (_slow n p)
 
 outside :: Time -> (Pattern a1 -> Pattern a) -> Pattern a1 -> Pattern a
 outside n = inside (1/n)
 
+loopFirst :: Pattern a -> Pattern a
 loopFirst p = splitQueries $ Pattern f
-  where f a@(s,e) = mapSnds' plus $ mapFsts' plus $ arc p (minus a)
+  where f a@(s,_) = mapSnds' plus $ mapFsts' plus $ arc p (minus a)
           where minus = mapArc (subtract (sam s))
                 plus = mapArc (+ (sam s))
 
@@ -1282,7 +1349,7 @@
 timeLoop n = outside n loopFirst
 
 seqPLoop :: [(Time, Time, Pattern a)] -> Pattern a
-seqPLoop ps = timeLoop (maxT - minT) $ minT <~ seqP ps
+seqPLoop ps = timeLoop (maxT - minT) $ minT `rotL` seqP ps
   where minT = minimum $ map fst' ps
         maxT = maximum $ map snd' ps
 
@@ -1305,8 +1372,9 @@
 for `swingBy (1%3)`
 -}
 swingBy::Time -> Time -> Pattern a -> Pattern a 
-swingBy x n = inside n (within (0.5,1) (x ~>))
+swingBy x n = inside n (within (0.5,1) (x `rotR`))
 
+swing :: Time -> Pattern a -> Pattern a 
 swing = swingBy (1%3)
 
 {- | `cycleChoose` is like `choose` but only picks a new item from the list
@@ -1314,7 +1382,7 @@
 cycleChoose::[a] -> Pattern a
 cycleChoose xs = Pattern $ \(s,e) -> [((s,e),(s,e), xs!!(floor $ (dlen xs)*(ctrand s) ))]
   where dlen xs = fromIntegral $ length xs
-        ctrand s = timeToRand $ fromIntegral $ floor $ sam s
+        ctrand s = (timeToRand :: Time -> Double) $ fromIntegral $ (floor :: Time -> Int) $ sam s
 
 {- | `shuffle n p` evenly divides one cycle of the pattern `p` into `n` parts,
 and returns a random permutation of the parts each cycle.  For example, 
@@ -1323,8 +1391,12 @@
 is not a permutation of the parts.
 -}
 shuffle::Int -> Pattern a -> Pattern a
-shuffle n = fit' 1 n (run n) (unwrap $ cycleChoose $ map listToPat $ 
-  permutations [0..n-1])
+shuffle n = fit' 1 n (_run n) (randpat n)
+  where randpat n = Pattern $ \(s,e) -> arc (p n $ sam s) (s,e)
+        p n c = listToPat $ map snd $ sort $ zip 
+                  [timeToRand (c+i/n') | i <- [0..n'-1]] [0..n-1]
+        n' :: Time
+        n' = fromIntegral n
 
 {- | `scramble n p` is like `shuffle` but randomly selects from the parts
 of `p` instead of making permutations. 
@@ -1332,34 +1404,46 @@
 `"a"` `"b"` and `"c"`, possibly repeating a single part.
 -}
 scramble::Int -> Pattern a -> Pattern a
-scramble n = fit' 1 n (run n) (density (fromIntegral n) $ 
+scramble n = fit' 1 n (_run n) (_density (fromIntegral n) $ 
   liftA2 (+) (pure 0) $ irand n)
 
 ur :: Time -> Pattern String -> [Pattern a] -> Pattern a
-ur t outer_p ps = slow t $ unwrap $ adjust <$> (timedValues $ (getPat . split) <$> outer_p)
+ur t outer_p ps = _slow t $ unwrap $ adjust <$> (timedValues $ (getPat . split) <$> outer_p)
   where split s = wordsBy (==':') s
         getPat (n:xs) = (ps' !!! read n, transform xs)
-        ps' = map (density t) ps
+        ps' = map (_density t) ps
         adjust (a, (p, f)) = f a p
         transform (x:_) a = transform' x a
         transform _ _ = id
         transform' "in" (s,e) p = twiddle (fadeIn) (s,e) p
         transform' "out" (s,e) p = twiddle (fadeOut) (s,e) p
         transform' _ _ p = p
-        twiddle f (s,e) p = s ~> (f (e-s) p)
+        twiddle f (s,e) p = s `rotR` (f (e-s) p)
 
 ur' :: Time -> Pattern String -> [(String, Pattern a)] -> [(String, Pattern a -> Pattern a)] -> Pattern a
-ur' t outer_p ps fs = slow t $ unwrap $ adjust <$> (timedValues $ (getPat . split) <$> outer_p)
+ur' t outer_p ps fs = _slow t $ unwrap $ adjust <$> (timedValues $ (getPat . split) <$> outer_p)
   where split s = wordsBy (==':') s
         getPat (s:xs) = (match s, transform xs)
         match s = fromMaybe silence $ lookup s ps'
-        ps' = map (fmap (density t)) ps
+        ps' = map (fmap (_density t)) ps
         adjust (a, (p, f)) = f a p
         transform (x:_) a = transform' x a
         transform _ _ = id
-        transform' str (s,e) p = s ~> (inside (1/(e-s)) (matchF str) p)
+        transform' str (s,e) p = s `rotR` (inside (1/(e-s)) (matchF str) p)
         matchF str = fromMaybe id $ lookup str fs
-        twiddle f (s,e) p = s ~> (f (e-s) p)
 
 inhabit :: [(String, Pattern a)] -> Pattern String -> Pattern a
 inhabit ps p = unwrap' $ (\s -> fromMaybe silence $ lookup s ps) <$> p
+
+repeatCycles :: Int -> Pattern a -> Pattern a
+repeatCycles n p = fastcat (replicate n p)
+
+{- | @spaceOut xs p@ repeats a pattern @p@ at different durations given by the list of time values in @xs@ -}
+spaceOut :: [Time] -> Pattern a -> Pattern a
+spaceOut xs p = _slow (toRational $ sum xs) $ stack $ map (\a -> compress a p) $ spaceArcs xs
+  where markOut :: Time -> [Time] -> [(Time, Time)]
+        markOut _ [] = []
+        markOut offset (x:xs) = (offset,offset+x):(markOut (offset+x) xs)
+        spaceArcs xs = map (\(a,b) -> (a/s,b/s)) $ markOut 0 xs
+        s = sum xs
+
diff --git a/Sound/Tidal/Strategies.hs b/Sound/Tidal/Strategies.hs
--- a/Sound/Tidal/Strategies.hs
+++ b/Sound/Tidal/Strategies.hs
@@ -19,7 +19,7 @@
 import Data.List (transpose)
 
 stutter :: Integral i => i -> Time -> Pattern a -> Pattern a
-stutter n t p = stack $ map (\i -> (t * (fromIntegral i)) ~> p) [0 .. (n-1)]
+stutter n t p = stack $ map (\i -> (t * (fromIntegral i)) `rotR` p) [0 .. (n-1)]
 
 echo, triple, quad, double :: Time -> Pattern a -> Pattern a
 echo   = stutter 2
@@ -127,9 +127,9 @@
 {- | an altenative form to `smash` is `smash'` which will use `chop` instead of `striate`.
 -}
 smash' n xs p = slowcat $ map (\n -> slow n p') xs
-  where p' = chop n p
+  where p' = _chop n p
 
--- samples "jvbass [~ latibro] [jvbass [latibro jvbass]]" ((1%2) <~ slow 6 "[1 6 8 7 3]")
+-- samples "jvbass [~ latibro] [jvbass [latibro jvbass]]" ((1%2) `rotL` slow 6 "[1 6 8 7 3]")
 
 samples :: Applicative f => f String -> f Int -> f String
 samples p p' = pick <$> p <*> p'
@@ -139,7 +139,7 @@
 
 {-
 scrumple :: Time -> Pattern a -> Pattern a -> Pattern a
-scrumple o p p' = p'' -- overlay p (o ~> p'')
+scrumple o p p' = p'' -- overlay p (o `rotR` p'')
   where p'' = Pattern $ \a -> concatMap
                               (\((s,d), vs) -> map (\x -> ((s,d),
                                                            snd x
@@ -164,10 +164,13 @@
 d1 $ slow 3 $ spin 4 $ sound "drum*3 tabla:4 [arpy:2 ~ arpy] [can:2 can:3]"
 @
 -}
-spin :: Int -> ParamPattern -> ParamPattern
-spin copies p =
+spin :: Pattern Int -> ParamPattern -> ParamPattern
+spin = temporalParam _spin
+
+_spin :: Int -> ParamPattern -> ParamPattern
+_spin copies p =
   stack $ map (\n -> let offset = toInteger n % toInteger copies in
-                     offset <~ p
+                     offset `rotL` p
                      # pan (pure $ fromRational offset)
               )
           [0 .. (copies - 1)]
@@ -185,7 +188,7 @@
 rand4 = ((*4) <$> rand)
 
 stackwith p ps | null ps = silence
-               | otherwise = stack $ map (\(i, p') -> p' # (((fromIntegral i) % l) <~ p)) (zip [0 ..] ps)
+               | otherwise = stack $ map (\(i, p') -> p' # (((fromIntegral i) % l) `rotL` p)) (zip [0 ..] ps)
   where l = fromIntegral $ length ps
 
 {-
@@ -226,15 +229,18 @@
 d1 $ chop 256 $ sound "bd*4 [sn cp] [hh future]*2 [cp feel]"
 @
 -}
-chop :: Int -> ParamPattern -> ParamPattern
-chop n p = Pattern $ \queryA -> concatMap (f queryA) $ arcCycles queryA
-     where f queryA a = concatMap (chopEvent queryA) (arc p a)
-           chopEvent (queryS, queryE) (a,_a',v) = map (newEvent v) $ filter (\(_, (s,e)) -> not $ or [e < queryS, s >= queryE]) (enumerate $ chopArc a n)
-           newEvent :: ParamMap -> (Int, Arc) -> Event ParamMap
-           newEvent v (i, a) = (a,a,Map.insert (param dirt "end") (VF ((fromIntegral $ i+1)/(fromIntegral n))) $ Map.insert (param dirt "begin") (VF ((fromIntegral i)/(fromIntegral n))) v)
 
-chop' tp p = unwrap $ (\tv -> chop tv p) <$> tp
+chop :: Pattern Int -> ParamPattern -> ParamPattern
+chop = temporalParam _chop
 
+_chop :: Int -> ParamPattern -> ParamPattern
+_chop n p = Pattern $ \queryA -> concatMap (f queryA) $ arcCycles queryA
+  where f queryA a = concatMap (chopEvent queryA) (arc p a)
+        chopEvent (queryS, queryE) (a,_a',v) = map (newEvent v) $ filter (\(_, (s,e)) -> not $ or [e < queryS, s >= queryE]) (enumerate $ chopArc a n)
+        newEvent :: ParamMap -> (Int, Arc) -> Event ParamMap
+        newEvent v (i, a) = (a,a,Map.insert (param dirt "end") (VF ((fromIntegral $ i+1)/(fromIntegral n))) $ Map.insert (param dirt "begin") (VF ((fromIntegral i)/(fromIntegral n))) v)
+
+
 {- | `gap` is similar to `chop` in that it granualizes every sample in place as it is played,
 but every other grain is silent. Use an integer value to specify how many granules
 each sample is chopped into:
@@ -243,8 +249,12 @@
 d1 $ gap 8 $ sound "jvbass"
 d1 $ gap 16 $ sound "[jvbass drum:4]"
 @-}
-gap :: Int -> ParamPattern -> ParamPattern
-gap n p = Pattern $ \queryA -> concatMap (f queryA) $ arcCycles queryA
+
+gap :: Pattern Int -> ParamPattern -> ParamPattern
+gap = temporalParam _gap
+
+_gap :: Int -> ParamPattern -> ParamPattern
+_gap n p = Pattern $ \queryA -> concatMap (f queryA) $ arcCycles queryA
      where f queryA a = concatMap (chopEvent queryA) (arc p a)
            chopEvent (queryS, queryE) (a,_a',v) = map (newEvent v) $ filter (\(_, (s,e)) -> not $ or [e < queryS, s >= queryE]) (enumerate $ everyOther $ chopArc a n)
            newEvent :: ParamMap -> (Int, Arc) -> Event ParamMap
@@ -297,7 +307,7 @@
 -}
 weave' :: Rational -> Pattern a -> [Pattern a -> Pattern a] -> Pattern a
 weave' t p fs | l == 0 = silence
-              | otherwise = slow t $ stack $ map (\(i, f) -> (fromIntegral i % l) <~ (density t $ f (slow t p))) (zip [0 ..] fs)
+              | otherwise = _slow t $ stack $ map (\(i, f) -> (fromIntegral i % l) `rotL` (_density t $ f (_slow t p))) (zip [0 ..] fs)
   where l = fromIntegral $ length fs
 
 {- | 
@@ -318,7 +328,7 @@
 
 -- | Step sequencing
 step :: String -> String -> Pattern String
-step s steps = cat $ map f steps
+step s steps = fastcat $ map f steps
     where f c | c == 'x' = atom s
               | c >= '0' && c <= '9' = atom $ s ++ ":" ++ [c]
               | otherwise = silence
@@ -328,17 +338,20 @@
 
 -- | like `step`, but allows you to specify an array of strings to use for 0,1,2...
 step' :: [String] -> String -> Pattern String
-step' ss steps = cat $ map f steps
+step' ss steps = fastcat $ map f steps
     where f c | c == 'x' = atom $ ss!!0
               | c >= '0' && c <= '9' = atom $ ss!!(Char.digitToInt c)
               | otherwise = silence
 
-off :: Time -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
-off t f p = superimpose (f . (t ~>)) p
+off :: Pattern Time -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
+off tp f p = unwrap $ (\tv -> _off tv f p) <$> tp
 
-offadd :: Num a => Time -> a -> Pattern a -> Pattern a
-offadd t n p = off t ((+n) <$>) p
+_off :: Time -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
+_off t f p = superimpose (f . (t `rotR`)) p
 
+offadd :: Num a => Pattern Time -> Pattern a -> Pattern a -> Pattern a
+offadd tp pn p = off tp (+pn) p
+
 {- | `up` does a poor man's pitchshift by semitones via `speed`.
 
 You can easily produce melodies from a single sample with up:
@@ -352,7 +365,7 @@
 up :: Pattern Double -> ParamPattern
 up = speed . ((1.059466**) <$>)
 
-ghost'' a f p = superimpose (((a*2.5) ~>) . f) $ superimpose (((a*1.5) ~>) . f) $ p
+ghost'' a f p = superimpose (((a*2.5) `rotR`) . f) $ superimpose (((a*1.5) `rotR`) . f) $ p
 ghost' a p = ghost'' 0.125 ((|*| gain (pure 0.7)) . (|=| end (pure 0.2)) . (|*| speed (pure 1.25))) p
 ghost p = ghost' 0.125 p 
 
@@ -376,8 +389,8 @@
 d1 $ juxBy 0.6 (|*| speed "2") $ slowspread (loopAt) [4,6,2,3] $ chop 12 $ sound "fm:14"
 @ 
 -}
-loopAt :: Time -> ParamPattern -> ParamPattern
-loopAt n p = slow n p |*| speed (pure $ fromRational $ 1/n) # unit (pure "c")
+loopAt :: Pattern Time -> ParamPattern -> ParamPattern
+loopAt n p = slow n p |*| speed (fromRational <$> (1/n)) # unit (pure "c")
 
 
 {- |
@@ -391,8 +404,8 @@
   where             
     weft n = concatMap (\x -> [[0..n-1],(reverse [0..n-1])]) [0 .. (n `div` 2) - 1]
     warp = transpose . weft
-    thread xs n p = slow (n%1) $ cat $ map (\i -> zoom (i%n,(i+1)%n) p) (concat xs)
+    thread xs n p = _slow (n%1) $ fastcat $ map (\i -> zoom (i%n,(i+1)%n) p) (concat xs)
     weftP n p = thread (weft n) n p
     warpP n p = thread (warp n) n p
-    maskedWeft n p = Sound.Tidal.Pattern.mask (every 2 rev $ density ((n)%2) "~ 1" :: Pattern Int) $ weftP n p
-    maskedWarp n p = mask (every 2 rev $ density ((n)%2) "1 ~" :: Pattern Int) $ warpP n p
+    maskedWeft n p = Sound.Tidal.Pattern.mask (every 2 rev $ _density ((n)%2) "~ 1" :: Pattern Int) $ weftP n p
+    maskedWarp n p = mask (every 2 rev $ _density ((n)%2) "1 ~" :: Pattern Int) $ warpP n p
diff --git a/Sound/Tidal/Stream.hs b/Sound/Tidal/Stream.hs
--- a/Sound/Tidal/Stream.hs
+++ b/Sound/Tidal/Stream.hs
@@ -39,18 +39,43 @@
 instance Show Param where
   show p = name p
 
+
 data Shape = Shape {params :: [Param],
                     latency :: Double,
                     cpsStamp :: Bool}
 
 
 data Value = VS { svalue :: String } | VF { fvalue :: Double } | VI { ivalue :: Int }
-           deriving (Show,Eq,Ord,Typeable)
+           deriving (Eq,Ord,Typeable)
 
+instance Show Value where
+  show (VS s) = s
+  show (VF f) = show f
+  show (VI i) = show i
+
+class ParamType a where
+  fromV :: Value -> Maybe a
+  toV :: a -> Value
+
+instance ParamType String where
+  fromV (VS s) = Just s
+  fromV _ = Nothing
+  toV s = VS s
+
+instance ParamType Double where
+  fromV (VF f) = Just f
+  fromV _ = Nothing
+  toV f = VF f
+
+instance ParamType Int where
+  fromV (VI i) = Just i
+  fromV _ = Nothing
+  toV i = VI i
+
 type ParamMap = Map.Map Param Value
 
 type ParamPattern = Pattern ParamMap
-           
+
 ticksPerCycle = 8
 
 defaultValue :: Param -> Value
@@ -162,6 +187,12 @@
         defaultV a = toValue a
         --defaultV Nothing = defaultValue nParam
 
+make' :: ParamType a => (a -> Value) -> Param -> Pattern a -> ParamPattern
+make' toValue par p = fmap (\x -> Map.singleton par (toValue x)) p
+
+makeP :: ParamType a => Param -> Pattern a -> ParamPattern
+makeP par p = coerce par $ fmap (\x -> Map.singleton par (toV x)) p
+
 makeS = make VS
 
 makeF :: Shape -> String -> Pattern Double -> ParamPattern
@@ -244,4 +275,55 @@
 copyParam fromParam toParam pat = f <$> pat
   where f m = maybe m (updateValue m) (Map.lookup fromParam m)
         updateValue m v = Map.union m (Map.fromList [(toParam,v)])
+
+get :: ParamType a => Param -> ParamPattern -> Pattern a
+get param p = filterJust $ fromV <$> (filterJust $ Map.lookup param <$> p)
+
+getI :: Param -> ParamPattern -> Pattern Int
+getI = get
+getF :: Param -> ParamPattern -> Pattern Double
+getF = get
+getS :: Param -> ParamPattern -> Pattern String
+getS = get
+
+with :: (ParamType a) => Param -> (Pattern a -> Pattern a) -> ParamPattern -> ParamPattern
+with param f p = p # (makeP param) ((\x -> f (get param x)) p)
+withI :: Param -> (Pattern Int -> Pattern Int) -> ParamPattern -> ParamPattern
+withI = with
+withF :: Param -> (Pattern Double -> Pattern Double) -> ParamPattern -> ParamPattern
+withF = with
+withS :: Param -> (Pattern String -> Pattern String) -> ParamPattern -> ParamPattern
+withS = with
+
+follow :: ParamType a => Param -> Param -> (Pattern a -> Pattern a) -> ParamPattern -> ParamPattern
+follow source dest f p = p # (makeP dest $ f (get source p))
+
+-- follow :: ParamType a => Param -> (Pattern a -> ParamPattern) -> ParamPattern -> ParamPattern
+-- follow source dest p = p # (dest $ get source p)
+
+follow' :: ParamType a => Param -> Param -> (Pattern a -> Pattern a) -> ParamPattern -> ParamPattern
+follow' source dest f p = p # (makeP dest $ f (get source p))
+
+followI :: Param -> Param -> (Pattern Int -> Pattern Int) -> ParamPattern -> ParamPattern
+followI = follow'
+followF :: Param -> Param -> (Pattern Double -> Pattern Double) -> ParamPattern -> ParamPattern
+followF = follow'
+followS :: Param -> Param -> (Pattern String -> Pattern String) -> ParamPattern -> ParamPattern
+followS = follow'
+
+-- with :: ParamType a => Param -> (Pattern a -> Pattern a) -> ParamPattern -> ParamPattern
+-- with source f p = p # (makeP source $ f (get source p))
+coerce :: Param -> ParamPattern -> ParamPattern
+coerce par@(S _ _) p = (Map.update f par) <$> p
+  where f (VS s) = Just (VS s)
+        f (VI i) = Just (VS $ show i)
+        f (VF f) = Just (VS $ show f)
+coerce par@(I _ _) p = (Map.update f par) <$> p
+  where f (VS s) = Just (VI $ read s)
+        f (VI i) = Just (VI i)
+        f (VF f) = Just (VI $ floor f)
+coerce par@(F _ _) p = (Map.update f par) <$> p
+  where f (VS s) = Just (VF $ read s)
+        f (VI i) = Just (VF $ fromIntegral i)
+        f (VF f) = Just (VF f)
 
diff --git a/Sound/Tidal/Transition.hs b/Sound/Tidal/Transition.hs
--- a/Sound/Tidal/Transition.hs
+++ b/Sound/Tidal/Transition.hs
@@ -124,5 +124,5 @@
 interpolateIn :: Time -> Time -> [ParamPattern] -> ParamPattern
 interpolateIn _ _ [] = silence
 interpolateIn _ _ (p:[]) = p
-interpolateIn t now (p:p':_) = do n <- now ~> (slow t envL)
+interpolateIn t now (p:p':_) = do n <- now `rotR` (_slow t envL)
                                   combineV (mixNums n) <$> p <*> p'
diff --git a/Sound/Tidal/Version.hs b/Sound/Tidal/Version.hs
new file mode 100644
--- /dev/null
+++ b/Sound/Tidal/Version.hs
@@ -0,0 +1,4 @@
+
+module Sound.Tidal.Version where
+
+tidal_version = "0.9.1"
diff --git a/tidal.cabal b/tidal.cabal
--- a/tidal.cabal
+++ b/tidal.cabal
@@ -1,14 +1,14 @@
 name:                tidal
-version:             0.9
+version:             0.9.1
 synopsis:            Pattern language for improvised music
 -- description:
-homepage:            http://tidal.lurk.org/
+homepage:            http://tidalcycles.org/
 license:             GPL-3
 license-file:        LICENSE
 author:              Alex McLean
 maintainer:          Alex McLean <alex@slab.org>, Mike Hodnick <mike.hodnick@gmail.com>
 Stability:           Experimental
-Copyright:           (c) Alex McLean and other contributors, 2016
+Copyright:           (c) Tidal contributors, 2017
 category:            Sound
 build-type:          Simple
 cabal-version:       >=1.6
@@ -35,6 +35,7 @@
                        Sound.Tidal.Transition
                        Sound.Tidal.Scales
                        Sound.Tidal.Chords
+                       Sound.Tidal.Version
 
   Build-depends:
       base < 5
@@ -49,6 +50,7 @@
     , safe
     , websockets > 0.8
     , mtl >= 2.1
+    , applicative-numbers
 
 source-repository head
   type:     git
diff --git a/tidal.el b/tidal.el
--- a/tidal.el
+++ b/tidal.el
@@ -59,7 +59,7 @@
   (tidal-send-string ":module Sound.Tidal.Context")
   (tidal-send-string "import qualified Sound.Tidal.Scales as Scales")
   (tidal-send-string "import qualified Sound.Tidal.Chords as Chords")
-  (tidal-send-string "(cps, getNow) <- cpsUtils")
+  (tidal-send-string "(cps, nudger, getNow) <- cpsUtils'")
   (tidal-send-string "(d1,t1) <- superDirtSetters getNow")
   (tidal-send-string "(d2,t2) <- superDirtSetters getNow")
   (tidal-send-string "(d3,t3) <- superDirtSetters getNow")
@@ -144,9 +144,9 @@
   (interactive)
   (tidal-send-string "now' <- getNow")
   (tidal-send-string "let now = nextSam now'")
-  (tidal-send-string "let retrig = (now ~>)")
-  (tidal-send-string "let fadeOut n = spread' (degradeBy) (retrig $ slow n $ envL)")
-  (tidal-send-string "let fadeIn n = spread' (degradeBy) (retrig $ slow n $ (1-) <$> envL)")
+  (tidal-send-string "let retrig = (now `rotR`)")
+  (tidal-send-string "let fadeOut n = spread' (_degradeBy) (retrig $ slow n $ envL)")
+  (tidal-send-string "let fadeIn n = spread' (_degradeBy) (retrig $ slow n $ (1-) <$> envL)")
 
   )
 
