diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # TidalCycles log of changes
 
+## 1.2.0 - Hunters Bar
+
+* Simplify <* and *>, removing any distinction between analogue and digital patterns
+
 ## 1.1.2 - Eccy Road
 
 * Usability fix for `binary` / `binaryN` (use squeezeJoin on input pattern)
diff --git a/src/Sound/Tidal/Control.hs b/src/Sound/Tidal/Control.hs
--- a/src/Sound/Tidal/Control.hs
+++ b/src/Sound/Tidal/Control.hs
@@ -392,10 +392,10 @@
 _getP d f pat = (fromMaybe d . f) <$> pat
 
 _cX :: a -> (Value -> Maybe a) -> String -> Pattern a
-_cX d f s = Pattern Analog $ \(State a m) -> queryArc (maybe (pure d) (_getP d f) $ Map.lookup s m) a
+_cX d f s = Pattern $ \(State a m) -> queryArc (maybe (pure d) (_getP d f) $ Map.lookup s m) a
 
 _cX_ :: (Value -> Maybe a) -> String -> Pattern a
-_cX_ f s = Pattern Analog $ \(State a m) -> queryArc (maybe silence (_getP_ f) $ Map.lookup s m) a
+_cX_ f s = Pattern $ \(State a m) -> queryArc (maybe silence (_getP_ f) $ Map.lookup s m) a
 
 cF :: Double -> String -> Pattern Double
 cF d = _cX d getF
diff --git a/src/Sound/Tidal/Core.hs b/src/Sound/Tidal/Core.hs
--- a/src/Sound/Tidal/Core.hs
+++ b/src/Sound/Tidal/Core.hs
@@ -17,7 +17,7 @@
 
 -- | Takes a function from time to values, and turns it into a 'Pattern'.
 sig :: (Time -> a) -> Pattern a
-sig f = Pattern Analog q
+sig f = Pattern q
   where q (State (Arc s e) _)
           | s > e = []
           | otherwise = [Event (Arc s e) (Arc s e) (f (s+((e-s)/2)))]
@@ -190,8 +190,7 @@
 -- in turn, then the second cycle from each, and so on.
 cat :: [Pattern a] -> Pattern a
 cat [] = silence
--- TODO I *guess* it would be digital..
-cat ps = Pattern Digital q
+cat ps = Pattern $ q
   where n = length ps
         q st = concatMap (f st) $ arcCyclesZW (arc st)
         f st a = query (withResultTime (+offset) p) $ st {arc = Arc (subtract offset (start a)) (subtract offset (stop a))}
@@ -234,10 +233,7 @@
 -- | 'overlay' combines two 'Pattern's into a new pattern, so that
 -- their events are combined over time. 
 overlay :: Pattern a -> Pattern a -> Pattern a
--- Analog if they're both analog
-overlay !p@(Pattern Analog _) !p'@(Pattern Analog _) = Pattern Analog $ \st -> query p st ++ query p' st
--- Otherwise digital. Won't really work to have a mixture.. Hmm
-overlay !p !p' = Pattern Digital $ \st -> query p st ++ query p' st
+overlay !p !p' = Pattern $ \st -> query p st ++ query p' st
 
 -- | An infix alias of @overlay@
 (<>) :: Pattern a -> Pattern a -> Pattern a
diff --git a/src/Sound/Tidal/Pattern.hs b/src/Sound/Tidal/Pattern.hs
--- a/src/Sound/Tidal/Pattern.hs
+++ b/src/Sound/Tidal/Pattern.hs
@@ -223,13 +223,8 @@
 -- | A function that represents events taking place over time
 type Query a = (State -> [Event a])
 
--- | Also known as Continuous vs Discrete/Amorphous vs Pulsating etc.
-data Nature = Analog | Digital
-            deriving (Eq, Show)
-
--- | A datatype that's basically a query, plus a hint about whether its events
--- are Analogue or Digital by nature
-data Pattern a = Pattern {nature :: Nature, query :: Query a}
+-- | A datatype that's basically a query
+data Pattern a = Pattern {query :: Query a}
 
 data Value = VS { svalue :: String }
            | VF { fvalue :: Double }
@@ -306,96 +301,39 @@
 
 instance NFData a => 
   NFData (Pattern a) where 
-    rnf (Pattern _ q) = rnf $ \s -> q s
+    rnf (Pattern q) = rnf $ \s -> q s
 
 instance Functor Pattern where
   -- | apply a function to all the values in a pattern
   fmap f p = p {query = fmap (fmap f) . query p}
 
-instance Applicative Pattern where
-  -- | Repeat the given value once per cycle, forever
-  pure v = Pattern Digital $ \(State a _) ->
-    map (\a' -> Event a' (sect a a') v) $ cycleArcsInArc a
-
-  (<*>) pf@(Pattern Digital _) px@(Pattern Digital _) = Pattern Digital q
+applyPatToPat :: (Arc -> Arc -> Maybe Arc) -> Pattern (a -> b) -> Pattern a -> Pattern b
+applyPatToPat combineWholes pf px = Pattern q
     where q st = catMaybes $ concatMap match $ query pf st
             where
               match (Event fWhole fPart f) =
                 map
                 (\(Event xWhole xPart x) ->
-                  do whole' <- subArc xWhole fWhole
+                  do whole' <- combineWholes fWhole xWhole
                      part' <- subArc fPart xPart
                      return (Event whole' part' (f x))
                 )
-                (query px $ st {arc = fPart})
-  (<*>) pf@(Pattern Digital _) px@(Pattern Analog _) = Pattern Digital q
-    where q st = concatMap match $ query pf st
-            where
-              match (Event fWhole fPart f) =
-                map
-                (Event fWhole fPart . f . value)
-                (query px $ st {arc = pure (start fPart)})
+                (query px $ st {arc = fWhole})
 
-  (<*>) pf@(Pattern Analog _) px@(Pattern Digital _) = Pattern Digital q
-    where q st = concatMap match $ query px st
-            where
-              match (Event xWhole xPart x) =
-                map
-                (\e -> Event xWhole xPart (value e x))
-                (query pf st {arc = pure (start xPart)})
+instance Applicative Pattern where
+  -- | Repeat the given value once per cycle, forever
+  pure v = Pattern $ \(State a _) ->
+    map (\a' -> Event a' (sect a a') v) $ cycleArcsInArc a
 
-  (<*>) pf px = Pattern Analog q
-    where q st = concatMap match $ query pf st
-            where
-              match ef =
-                map
-                (Event (arc st) (arc st) . value ef . value)
-                (query px st)
+  (<*>) = applyPatToPat subArc
 
--- | Like <*>, but the structure only comes from the left
+-- | Like <*>, but the 'wholes' come from the left
 (<*) :: Pattern (a -> b) -> Pattern a -> Pattern b
-(<*) pf@(Pattern Analog _) px@(Pattern Analog _) = Pattern Analog q
-  where q st = concatMap match $ query pf st
-          where
-            match (Event fWhole fPart f) =
-              map
-              (Event fWhole fPart . f . value) $
-              query px st -- for continuous events, use the original query
-
--- If one of the patterns is digital, treat both as digital.. (TODO - needs extra thought)
-(<*) pf px = Pattern Digital q
-    where q st = catMaybes $ concatMap match $ query pf st
-            where
-              match (Event fWhole fPart f) =
-                map
-                (\(Event _ xPart x) ->
-                  do let whole' = fWhole
-                     part' <- subArc fPart xPart
-                     return (Event whole' part' (f x))
-                )
-                (query px $ st {arc = fPart})
+(<*) = applyPatToPat (\a _ -> Just a)
 
--- | Like <*>, but the structure only comes from the right
+-- | Like <*>, but the 'wholes' come from the right
 (*>) :: Pattern (a -> b) -> Pattern a -> Pattern b
-(*>) pf@(Pattern Analog _) px@(Pattern Analog _) = Pattern Analog q
-  where q st = concatMap match $ query px st
-          where
-            match (Event xWhole xPart x) =
-              map
-              (\e -> Event xWhole xPart (value e x)) $
-              query pf st -- for continuous events, use the original query
-
-(*>) pf px = Pattern Digital q
-    where q st = catMaybes $ concatMap match $ query pf st
-            where
-              match (Event _ fPart f) =
-                map
-                (\(Event xWhole xPart x) ->
-                  do let whole' = xWhole
-                     part' <- subArc fPart xPart
-                     return (Event whole' part' (f x))
-                )
-                (query px $ st {arc = fPart})
+(*>) = applyPatToPat (\_ b -> Just b)
 
 infixl 4 <*, *>
 
@@ -659,16 +597,10 @@
 -- * Internal functions
 
 empty :: Pattern a
-empty = Pattern {nature = Digital, query = const []}
+empty = Pattern {query = const []}
 
 queryArc :: Pattern a -> Arc -> [Event a]
 queryArc p a = query p $ State a Map.empty 
-
-isDigital :: Pattern a -> Bool
-isDigital = (== Digital) . nature
-
-isAnalog :: Pattern a -> Bool
-isAnalog = not . isDigital
 
 -- | Splits queries that span cycles. For example `query p (0.5, 1.5)` would be
 -- turned into two queries, `(0.5,1)` and `(1,1.5)`, and the results
diff --git a/src/Sound/Tidal/UI.hs b/src/Sound/Tidal/UI.hs
--- a/src/Sound/Tidal/UI.hs
+++ b/src/Sound/Tidal/UI.hs
@@ -79,7 +79,7 @@
 @
 -}
 rand :: Fractional a => Pattern a
-rand = Pattern Analog (\(State a@(Arc s e) _) -> [Event a a (realToFrac $ timeToRand $ (e + s)/2)])
+rand = Pattern (\(State a@(Arc s e) _) -> [Event a a (realToFrac $ timeToRand $ (e + s)/2)])
 
 {- | 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:
@@ -987,7 +987,7 @@
 
 -- TODO - what does this do? Something for @stripe@ ..
 randStruct :: Int -> Pattern Int
-randStruct n = splitQueries $ Pattern {nature = Digital, query = f}
+randStruct n = splitQueries $ Pattern {query = f}
   where f st = map (\(a,b,c) -> Event a (fromJust b) c) $ filter (\(_,x,_) -> isJust x) as
           where as = map (\(i, Arc s' e') ->
                     (Arc (s' + sam s) (e' + sam s),
@@ -1088,7 +1088,7 @@
 markovPat = tParam2 _markovPat
 
 _markovPat :: Int -> Int -> [[Double]] -> Pattern Int
-_markovPat n xi tp = splitQueries $ Pattern Digital (\(State a@(Arc s e) _) -> 
+_markovPat n xi tp = splitQueries $ Pattern (\(State a@(Arc s e) _) -> 
   queryArc (listToPat $ runMarkov n tp xi (sam s)) a)
 
 {-|
@@ -1281,7 +1281,7 @@
 randrun :: Int -> Pattern Int
 randrun 0 = silence
 randrun n' =
-  splitQueries $ Pattern Digital (\(State a@(Arc s _) _) -> events a $ sam s)
+  splitQueries $ Pattern (\(State a@(Arc s _) _) -> events a $ sam s)
   where events a seed = mapMaybe toEv $ zip arcs shuffled
           where shuffled = map snd $ sortOn fst $ zip rs [0 .. (n'-1)]
                 rs = timeToRands seed n'
@@ -1718,7 +1718,7 @@
 -- | Serialises a pattern so there's only one event playing at any one
 -- time, making it 'monophonic'. Events which start/end earlier are given priority.
 mono :: Pattern a -> Pattern a
-mono p = Pattern Digital $ \(State a cm) -> flatten $ query p (State a cm) where
+mono p = Pattern $ \(State a cm) -> flatten $ query p (State a cm) where
   flatten :: [Event a] -> [Event a]
   flatten = mapMaybe constrainPart . truncateOverlaps . sortOn whole
   truncateOverlaps [] = []
@@ -1739,7 +1739,7 @@
 -- smooth :: Pattern Double -> Pattern Double
 
 smooth :: Fractional a => Pattern a -> Pattern a
-smooth p = Pattern Analog $ \st@(State a cm) -> tween st a $ query monoP (State (midArc a) cm)
+smooth p = Pattern $ \st@(State a cm) -> tween st a $ query monoP (State (midArc a) cm)
   where
     midArc a = Arc (mid (start a, stop a)) (mid (start a, stop a))
     tween _ _ [] = []
diff --git a/src/Sound/Tidal/Version.hs b/src/Sound/Tidal/Version.hs
--- a/src/Sound/Tidal/Version.hs
+++ b/src/Sound/Tidal/Version.hs
@@ -1,4 +1,4 @@
 module Sound.Tidal.Version where
 
 tidal_version :: String
-tidal_version = "1.1.2"
+tidal_version = "1.2.0"
diff --git a/test/Sound/Tidal/CoreTest.hs b/test/Sound/Tidal/CoreTest.hs
--- a/test/Sound/Tidal/CoreTest.hs
+++ b/test/Sound/Tidal/CoreTest.hs
@@ -105,14 +105,14 @@
         (map value $ queryArc ((+1) <$> saw) (Arc 0.5 0.5)) `shouldBe` [1.5 :: Float]
       it "works on the left of <*>" $ do
         (queryArc ((+) <$> saw <*> pure 3) (Arc 0 1))
-          `shouldBe` fmap toEvent [(((0,1), (0,1)), 3 :: Float)]
+          `shouldBe` fmap toEvent [(((0,1), (0,1)), 3.5 :: Float)]
       it "works on the right of <*>" $ do
         (queryArc ((fast 4 $ pure (+3)) <*> saw) (Arc 0 1))
           `shouldBe` fmap toEvent
-          [(((0,0.25), (0,0.25)), 3 :: Float),
-            (((0.25,0.5), (0.25,0.5)), 3.25),
-            (((0.5,0.75), (0.5,0.75)), 3.5),
-            (((0.75,1), (0.75,1)), 3.75)
+          [(((0,0.25), (0,0.25)), 3.125 :: Float),
+            (((0.25,0.5), (0.25,0.5)), 3.375),
+            (((0.5,0.75), (0.5,0.75)), 3.625),
+            (((0.75,1), (0.75,1)), 3.875)
           ]
       it "can be reversed" $ do
         it "works with whole cycles" $
diff --git a/test/Sound/Tidal/UITest.hs b/test/Sound/Tidal/UITest.hs
--- a/test/Sound/Tidal/UITest.hs
+++ b/test/Sound/Tidal/UITest.hs
@@ -44,7 +44,7 @@
       it "can hold a value over multiple cycles" $ do
         comparePD (Arc 0 8)
           (segment 0.5 saw)
-          (slow 2 "0.5" :: Pattern Double)
+          (slow 2 "0" :: Pattern Double)
       {-
       -- not sure what this is supposed to do!
       it "holding values over multiple cycles works in combination" $ do
diff --git a/tidal.cabal b/tidal.cabal
--- a/tidal.cabal
+++ b/tidal.cabal
@@ -1,5 +1,5 @@
 name:                tidal
-version:             1.1.2
+version:             1.2.0
 synopsis:            Pattern language for improvised music
 -- description:
 homepage:            http://tidalcycles.org/
