diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -13,21 +13,25 @@
 This library provides two syntax constructs, `matchAll`, `match`, `matchAllDFS`, and `matchDFS` for advanced pattern matching for non-free data types.
 
 ```
-e = hs-expr                    -- arbitrary Haskell expression
-  | matchAll e e [C, ...]      -- match-all expression
-  | match e e [C, ...]         -- match expression
-  | matchAllDFS e e [C, ...]   -- match-all expression
-  | matchDFS e e [C, ...]      -- match expression
-  | Something                  -- Something built-in matcher
+e ::= hs-expr                    -- arbitrary Haskell expression
+    | matchAll e e [C, ...]      -- match-all expression
+    | match e e [C, ...]         -- match expression
+    | matchAllDFS e e [C, ...]   -- match-all expression
+    | matchDFS e e [C, ...]      -- match expression
+    | Something                  -- Something built-in matcher
 
-C = [mc| p => e |]             -- match clause
+C ::= [mc| p -> e |]             -- match clause
 
-p = _                          -- wildcard
-  | $x                         -- pattern variable
-  | #e                         -- value pattern
-  | (& p ...)                  -- and-pattern
-  | (| p ...)                  -- or-pattern
-  | (not p)                    -- not-pattern
+p ::= _                          -- wildcard pattern
+    | $v                         -- pattern variable
+    | #e                         -- value pattern
+    | ?e                         -- predicate pattern
+    | (p_1, p_2, ..., p_n)       -- tuple pattern
+    | [p_1, p_2, ..., p_n]       -- collection pattern
+    | p & p                      -- and-pattern
+    | p | p                      -- or-pattern
+    | !p                         -- not-pattern
+    | c p_1 p_2 ... p_n          -- constructor pattern
 ```
 
 ## Usage
@@ -39,7 +43,7 @@
 This expression returns a list of a single element because there is only one decomposition.
 
 ```
-matchAll [1,2,3] (List Integer) [[mc| cons $x $xs => (x, xs)|]]
+matchAll [1,2,3] (List Integer) [[mc| $x : $xs -> (x, xs)|]]
 -- [(1,[2,3])]
 ```
 
@@ -51,11 +55,11 @@
 For example, by changing the matcher of the above `matchAll` from `List Integer` to `Multiset Integer`, the evaluation result changes as follows:
 
 ```
-matchAll [1,2,3] (Multiset Integer) [[mc| cons $x $xs => (x, xs)|]]
+matchAll [1,2,3] (Multiset Integer) [[mc| $x : $xs -> (x, xs)|]]
 -- [(1,[2,3]),(2,[1,3]),(3,[1,2])]
 ```
 
-When the `Multiset` matcher is used, the `cons` pattern decomposes a target list into an element and the rest elements.
+When the `Multiset` matcher is used, `:` (the cons pattern) decomposes a target list into an element and the rest elements.
 
 The pattern-matching algorithms for each matcher can be defined by users.
 For example, the matchers such as `List` and `Multiset` can be defined by users.
@@ -72,7 +76,7 @@
 A non-linear pattern is effectively used for expressing the pattern.
 
 ```
-matchAll [1,2,5,9,4] (Multiset Integer) [[mc| cons $x (cons #(x+1) _) => x|]]
+matchAll [1,2,5,9,4] (Multiset Integer) [[mc| $x : #(x+1) : _ -> x|]]
 -- [1,4]
 ```
 
@@ -82,7 +86,7 @@
 The `match` expression returns only the evaluation result of the first pattern-matching result.
 
 ```
-match [1,2,5,9,4] (Multiset Integer) [[mc| cons $x (cons #(x+1) _) => x|]]
+match [1,2,5,9,4] (Multiset Integer) [[mc| $x : #(x+1) : _ -> x|]]
 -- 1
 ```
 
@@ -100,7 +104,7 @@
 
 ```
 take 10 (matchAll [1..] (Set Integer)
-           [[mc| cons $x (cons $y _) => (x, y) |]])
+           [[mc| $x : $y : _ -> (x, y) |]])
 -- [(1,1),(1,2),(2,1),(1,3),(2,2),(3,1),(1,4),(2,3),(3,2),(4,1)]
 ```
 
@@ -108,7 +112,7 @@
 
 ```
 take 10 (matchAllDFS [1..] (Set Integer)
-           [[mc| cons $x (cons $y _) => (x, y) |]])
+           [[mc| $x : $y : _ -> (x, y) |]])
 -- [(1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(1,8),(1,9),(1,10)]
 ```
 
@@ -123,10 +127,10 @@
 preparing...
 
 ```
-matchAll (1,2) UnorderedEqlPair [[mc| uepair $x $y => (x,y) |]]
+matchAll (1,2) UnorderedEqlPair [[mc| uepair $x $y -> (x,y) |]]
 -- [(1,2),(2,1)]
 
-matchAll (1,2) UnorderedEqlPair [[mc| uepair #2 $x => x |]]
+matchAll (1,2) UnorderedEqlPair [[mc| uepair #2 $x -> x |]]
 -- [1]
 ```
 
@@ -136,7 +140,7 @@
 
 ```
 data UnorderedEqlPair = UnorderedEqlPair
-instance (Eq a) => Matcher UnorderedEqlPair (a, a)
+instance (Eq a) -> Matcher UnorderedEqlPair (a, a)
 
 uepair :: (Eq a)
        => Pattern a Eql ctx xs
@@ -176,7 +180,7 @@
 
 ```
 take 10 (matchAll primes (List Integer)
-           [[mc| join _ (cons $p (cons #(p+2) _)) => (p, p+2) |]])
+           [[mc| _ ++ $p : #(p+2) : _ -> (p, p+2) |]])
 -- [(3,5),(5,7),(11,13),(17,19),(29,31),(41,43),(59,61),(71,73),(101,103),(107,109)]
 ```
 
@@ -184,7 +188,7 @@
 
 ```
 take 10 (matchAll primes (List Integer)
-           [[mc| join _ (cons $p (join _ (cons #(p+6) _))) => (p, p+6) |]])
+           [[mc| _ ++ $p : _ ++ #(p+6) : _ -> (p, p+6) |]])
 -- [(5,11),(7,13),(11,17),(13,19),(17,23),(23,29),(31,37),(37,43),(41,47),(47,53)]
 ```
 
@@ -193,55 +197,55 @@
 ```
 poker cs =
   match cs (Multiset CardM)
-    [[mc| cons (card $s $n)
-           (cons (card #s #(n-1))
-            (cons (card #s #(n-2))
-             (cons (card #s #(n-3))
-              (cons (card #s #(n-4))
-               _)))) => "Straight flush" |],
-     [mc| cons (card _ $n)
-           (cons (card _ #n)
-            (cons (card _ #n)
-             (cons (card _ #n)
-              (cons _
-               _)))) => "Four of a kind" |],
-     [mc| cons (card _ $m)
-           (cons (card _ #m)
-            (cons (card _ #m)
-             (cons (card _ $n)
-              (cons (card _ #n)
-                _)))) => "Full house" |],
-     [mc| cons (card $s _)
-           (cons (card #s _)
-            (cons (card #s _)
-             (cons (card #s _)
-              (cons (card #s _)
-               _)))) => "Flush" |],
-     [mc| cons (card _ $n)
-           (cons (card _ #(n-1))
-            (cons (card _ #(n-2))
-             (cons (card _ #(n-3))
-              (cons (card _ #(n-4))
-               _)))) => "Straight" |],
-     [mc| cons (card _ $n)
-           (cons (card _ #n)
-            (cons (card _ #n)
-             (cons _
-              (cons _
-               _)))) => "Three of a kind" |],
-     [mc| cons (card _ $m)
-           (cons (card _ #m)
-            (cons (card _ $n)
-             (cons (card _ #n)
-              (cons _
-                _)))) => "Two pair" |],
-     [mc| cons (card _ $n)
-           (cons (card _ #n)
-            (cons _
-             (cons _
-              (cons _
-               _)))) => "One pair" |],
-     [mc| _ => "Nothing" |]]
+    [[mc| card $s $n :
+           card #s #(n-1) :
+            card #s #(n-2) :
+             card #s #(n-3) :
+              card #s #(n-4) :
+               [] -> "Straight flush" |],
+     [mc| card _ $n :
+           card _ #n :
+            card _ #n :
+             card _ #n :
+              _ :
+               [] -> "Four of a kind" |],
+     [mc| card _ $m :
+           card _ #m :
+            card _ #m :
+             card _ $n :
+              card _ #n :
+               [] -> "Full house" |],
+     [mc| card $s _ :
+           card #s _ :
+            card #s _ :
+             card #s _ :
+              card #s _ :
+               [] -> "Flush" |],
+     [mc| card _ $n :
+           card _ #(n-1) :
+            card _ #(n-2) :
+             card _ #(n-3) :
+              card _ #(n-4) :
+               [] -> "Straight" |],
+     [mc| card _ $n :
+           card _ #n :
+            card _ #n :
+             _ :
+              _ :
+               [] -> "Three of a kind" |],
+     [mc| card _ $m :
+           card _ #m :
+            card _ $n :
+             card _ #n :
+              _ :
+               [] -> "Two pair" |],
+     [mc| card _ $n :
+           card _ #n :
+            _ :
+             _ :
+              _ :
+               [] -> "One pair" |],
+     [mc| _ -> "Nothing" |]]
 ```
 
 ## Benchmark
@@ -261,7 +265,7 @@
 main = do
   let n = 100
   let ans = take n (matchAll primes (List Integer)
-                     [[mc| join _ (cons $p (cons #(p+2) _)) => (p, p+2) |]])
+                     [[mc| _ ++ $p : #(p+2) : _ -> (p, p+2) |]])
   putStrLn $ show ans
 $ stack ghc -- benchmark/prime-pairs-2.hs
 $ time ./benchmark/prime-pairs-2
diff --git a/mini-egison.cabal b/mini-egison.cabal
--- a/mini-egison.cabal
+++ b/mini-egison.cabal
@@ -1,7 +1,7 @@
 cabal-version: 1.12
 
 name:           mini-egison
-version:        0.1.6
+version:        1.0.0
 synopsis:    Template Haskell Implementation of Egison Pattern Matching
 description: This package provides the pattern-matching facility that fulfills the following three criteria for practical pattern matching for non-free data types\: (i) non-linear pattern matching with backtracking; (ii) extensibility of pattern-matching algorithms; (iii) ad-hoc polymorphism of patterns.
   Non-free data types are data types whose data have no standard forms.
@@ -38,11 +38,13 @@
       src
   build-depends:
       base >=4.7 && <5
-    , containers
-    , split
+    , mtl
+    , recursion-schemes
+    , haskell-src-exts
     , haskell-src-meta
-    , regex-compat
     , template-haskell
+    , egison-pattern-src >= 0.2.1 && < 0.3
+    , egison-pattern-src-th-mode >= 0.2.1 && < 0.3
   default-language: Haskell2010
   default-extensions:
       TemplateHaskell
@@ -54,7 +56,11 @@
     , TypeFamilies
     , TypeOperators
     , FlexibleInstances
+    , FlexibleContexts
     , TupleSections
+    , Strict
+    , StrictData
+    , NamedFieldPuns
   ghc-options:  -O3
   
 test-suite mini-egison-test
diff --git a/sample/cdcl.hs b/sample/cdcl.hs
--- a/sample/cdcl.hs
+++ b/sample/cdcl.hs
@@ -71,8 +71,8 @@
 addVars :: [Integer] -> [(Integer, Integer)] -> [(Integer, Integer)]
 addVars vs vars =
   matchDFS (vs, vars) (Pair (List Literal) (List (Pair Literal M.Integer)))
-    [[mc| pair nil _ => sortBy (\(_, c1) (_, c2) -> opposite (compare c1 c2)) vars |],
-     [mc| pair (cons $v $vs2) (join $hs (cons (pair #v $c) $ts)) =>
+    [[mc| ([], _) -> sortBy (\(_, c1) (_, c2) -> opposite (compare c1 c2)) vars |],
+     [mc| ($v : $vs2, $hs ++ (#v, $c) : $ts) ->
           addVars vs2 (hs ++ (v, c + 1) : ts) |]]
  where
    opposite LT = GT
@@ -82,7 +82,7 @@
 deleteVar :: Integer -> [(Integer, Integer)] -> [(Integer, Integer)]
 deleteVar v vars =
   matchDFS vars (Multiset (Pair Literal M.Integer))
-    [[mc| cons (pair #v _) (cons (pair #(negate v) _) $vars2) => vars2 |]]
+    [[mc| (#v, _) : (#(negate v), _) : $vars2 -> vars2 |]]
 
 --
 -- Utility functions for literals and cnfs
@@ -90,19 +90,19 @@
 getStage :: Integer -> [Assign] -> Integer
 getStage l trail =
   matchDFS trail (List Assignment)
-    [[mc| join _ (cons (whichever (pair #(negate l) $s)) _) => s |]]
+    [[mc| _ ++ whichever (#(negate l), $s) : _ -> s |]]
 
 deleteLiteral :: Integer -> [([Integer], [Integer])] -> [([Integer], [Integer])]
 deleteLiteral l cnf =
   map (\(c1, c2) -> (matchAll c1 (Multiset Literal)
-                       [[mc| cons (& (not #l) $m) _ => m |]],
+                       [[mc| (!#l & $m) : _ -> m |]],
                      c2))
       cnf
 
 deleteClausesWith :: Integer -> [([Integer], [Integer])] -> [([Integer], [Integer])]
 deleteClausesWith l cnf =
   matchAll cnf (Multiset (Pair (Multiset Literal) (Multiset Literal)))
-    [[mc| cons (& (pair (not (cons #l _)) _) $c) _ => c |]]
+    [[mc| ((!(#l : _), _) & $c) : _ -> c |]]
 
 assignTrue :: Integer -> [([Integer], [Integer])] -> [([Integer], [Integer])]
 assignTrue l cnf =
@@ -117,17 +117,17 @@
 unitPropagate' :: Integer -> [([Integer], [Integer])] -> [Assign] -> [Assign] -> ([([Integer], [Integer])], [Assign])
 unitPropagate' stage cnf trail otrail =
   matchDFS trail (List Assignment)
-    [[mc| cons (whichever (pair $l _)) $trail2 => unitPropagate' stage (assignTrue l cnf) trail2 otrail |],
-     [mc| _ => unitPropagate'' stage cnf otrail |]]
+    [[mc| whichever ($l, _) : $trail2 -> unitPropagate' stage (assignTrue l cnf) trail2 otrail |],
+     [mc| _ -> unitPropagate'' stage cnf otrail |]]
    
 unitPropagate'' :: Integer -> [([Integer], [Integer])] -> [Assign] -> ([([Integer], [Integer])], [Assign])
 unitPropagate'' stage cnf trail =
   matchDFS cnf (Multiset (Pair (Multiset Literal) (Multiset Literal)))
-    [[mc| cons (pair nil _) _ => (cnf, trail) |],
-     [mc| cons (pair (cons $l nil) (cons #l $rs)) _ =>
+    [[mc| ([], _) : _ -> (cnf, trail) |],
+     [mc| ($l : [], #l : $rs) : _ ->
           unitPropagate'' stage (assignTrue l cnf) 
                           ([(Deduced (l, stage) (map (\r -> (r, (getStage r trail))) rs))] ++ trail) |],
-     [mc| _ => (cnf, trail) |]]
+     [mc| _ -> (cnf, trail) |]]
 
 --
 -- Learning
@@ -136,10 +136,10 @@
 learn :: Integer -> [(Integer, Integer)] -> [Assign] -> (Integer, [Integer])
 learn stage cl trail =
   matchDFS (trail, cl) (Pair (List Assignment) (Multiset (Pair Literal M.Integer))) -- must be matchDFS
-    [[mc| pair _ (not (cons (pair _ #stage) (cons (pair _ #stage) _))) =>
+    [[mc| (_, !((_, #stage) : (_, #stage) : _)) ->
           (minimum (map (\(_, c) -> c) cl), map (\(l, _) -> l) cl) |],
-     [mc| pair (join _ (cons (deduced (pair $l #stage) $ds) $trail2))
-               (cons (pair #(negate l) #stage) $rs) =>
+     [mc| (_ ++ deduced ($l, #stage) $ds : $trail2,
+               (#(negate l), #stage) : $rs) ->
           learn stage (union rs ds) trail2 |]]
 
 --
@@ -149,8 +149,8 @@
 backjump :: Integer -> [Assign] -> [Assign]
 backjump stage trail =
   matchDFS trail (List Assignment)
-    [[mc| join _ (& (cons (guessed (pair _ #stage)) _) $trail2) => trail2 |],
-     [mc| _ => [] |]]
+    [[mc| _ ++ ((guessed (_, #stage) : _) & $trail2) -> trail2 |],
+     [mc| _ -> [] |]]
 
 --
 -- Guess
@@ -158,8 +158,8 @@
 
 guess vars trail =
   matchDFS (vars, trail) (Pair (List (Pair Literal M.Integer)) (List Assignment)) -- must be matchDFS
-    [[mc| pair (join _ (cons (pair $l _) _))
-               (not (join _ (cons (whichever (pair (| #l #(negate l)) _)) _))) =>
+    [[mc| (_ ++ ($l, _) : _,
+               (!(_ ++ whichever ((#l | #(negate l)), _) : _))) ->
           negate l |]]
 
 --
@@ -174,13 +174,13 @@
   let (cnf2, trail2) = unitPropagate stage cnf trail in
 --  let (cnf2, trail2) = unitPropagate stage cnf (trace (show trail) trail) in -- debug
     matchDFS (cnf2, trail2) (Pair (Multiset (Pair (Multiset Literal) (Multiset Literal))) (List Assignment))
-      [[mc| pair nil _ => True |],
-       [mc| pair (cons (pair nil $cc) _) (join _ (cons (guessed (pair $l #stage)) $trail3)) =>
+      [[mc| ([], _) -> True |],
+       [mc| (([], $cc) : _, _ ++ guessed ($l, #stage) : $trail3) ->
             let (s, lc) = learn stage (map (\l -> (l, (getStage l trail2))) cc) trail2 in
             let trail4 = backjump s trail3 in
               cdcl' (count + 1) s (addVars lc vars) ((lc, lc):cnf) trail4 |],
-       [mc| pair (cons (pair nil $cc) _) _ => False |],
-       [mc| _ =>
+       [mc| (([], $cc) : _, _) -> False |],
+       [mc| _ ->
             let g = guess vars trail2 in
               cdcl' (count + 1) (stage + 1) vars cnf (Guessed (g, stage + 1):trail2) |]]
 
diff --git a/src/Control/Egison/Core.hs b/src/Control/Egison/Core.hs
--- a/src/Control/Egison/Core.hs
+++ b/src/Control/Egison/Core.hs
@@ -93,14 +93,17 @@
       Refl -> MCons atom (mappend atoms1 atoms2)
 
 -- | Create a list of a single matching atom.
+{-# INLINE oneMAtom #-}
 oneMAtom :: MAtom ctx xs -> MList ctx xs
 oneMAtom atom1 = MCons atom1 MNil
 
 -- | Create a list of two matching atoms.
+{-# INLINE twoMAtoms #-}
 twoMAtoms :: MAtom ctx xs -> MAtom (ctx :++: xs) ys -> MList ctx (xs :++: ys)
 twoMAtoms atom1 atom2 = MCons atom1 (MCons atom2 MNil)
 
 -- | Create a list of three matching atoms.
+{-# INLINE threeMAtoms #-}
 threeMAtoms :: MAtom ctx xs -> MAtom (ctx :++: xs) ys -> MAtom (ctx :++: xs :++: ys) zs -> MList ctx (xs :++: ys :++: zs)
 threeMAtoms atom1 atom2 atom3 =
   case threeMConsAssocProof atom1 atom2 atom3 of
@@ -123,15 +126,19 @@
 happend xs@(HCons x xs') ys = case hconsAssocProof x xs' ys of
                                 Refl -> HCons x $ happend xs' ys
 
+{-# INLINE hconsAssocProof #-}
 hconsAssocProof :: a -> HList as -> HList bs -> ((a ': as) :++: bs) :~: (a ': (as :++: bs))
 hconsAssocProof _ _ HNil = Refl
 hconsAssocProof x xs (HCons y ys) = Refl
 
+{-# INLINE mconsAssocProof #-}
 mconsAssocProof :: MAtom ctx vs -> MList (ctx :++: vs) vs' -> (ctx :++: (vs :++: vs')) :~: ((ctx :++: vs) :++: vs')
 mconsAssocProof _ _ = unsafeCoerce Refl -- Todo: Write proof.
 
+{-# INLINE mappendAssocProof #-}
 mappendAssocProof :: MAtom ctx xs -> MList (ctx :++: xs) ys ->  MList (ctx :++: xs :++: ys) zs -> (xs :++: (ys :++: zs)) :~: ((xs :++: ys) :++: zs)
 mappendAssocProof _ _ _ = unsafeCoerce Refl -- Todo: Write proof.
 
+{-# INLINE threeMConsAssocProof #-}
 threeMConsAssocProof :: MAtom ctx xs -> MAtom (ctx :++: xs) ys -> MAtom (ctx :++: xs :++: ys) zs -> (xs :++: ys :++: zs) :~: (xs :++: (ys :++: zs))
 threeMConsAssocProof _ _ _ = unsafeCoerce Refl -- Todo: Write proof.
diff --git a/src/Control/Egison/Match.hs b/src/Control/Egison/Match.hs
--- a/src/Control/Egison/Match.hs
+++ b/src/Control/Egison/Match.hs
@@ -15,26 +15,32 @@
 -- | @matchAll@ takes a target, a matcher, and a list of match clauses.
 -- @matchAll@ collects all the pattern-matching results and returns a list of the results evaluating the body expression for each pattern-matching result.
 -- @matchAll@ traverses a search tree for pattern matching in breadth-first order.
+{-# INLINE matchAll #-}
 matchAll :: (Matcher m a) => a -> m -> [MatchClause a m b] -> [b]
-matchAll tgt m [] = []
-matchAll tgt m ((MatchClause pat f):cs) =
-  let results = processMStatesAll [[MState HNil (MCons (MAtom pat m tgt) MNil)]] in
-  map f results ++ matchAll tgt m cs
+matchAll tgt m = foldr go []
+  where
+    go (MatchClause pat f) acc =
+      let results = processMStatesAll [[MState HNil (MCons (MAtom pat m tgt) MNil)]] in
+      map f results ++ acc
 
 -- | @match@ takes a target, a matcher, and a list of match clauses.
 -- @match@ calculates only the first pattern-matching result and returns the results evaluating the body expression for the first pattern-matching result.
 -- @match@ traverses a search tree for pattern matching in breadth-first order.
+{-# INLINE match #-}
 match :: (Matcher m a) => a -> m -> [MatchClause a m b] -> b
 match tgt m cs = head $ matchAll tgt m cs
 
 -- | @matchAllDFS@ is much similar to @matchAll@ but traverses a search tree for pattern matching in depth-first order.
+{-# INLINE matchAllDFS #-}
 matchAllDFS :: (Matcher m a) => a -> m -> [MatchClause a m b] -> [b]
-matchAllDFS tgt m [] = []
-matchAllDFS tgt m ((MatchClause pat f):cs) =
-  let results = processMStatesAllDFS [MState HNil (MCons (MAtom pat m tgt) MNil)] in
-  map f results ++ matchAllDFS tgt m cs
+matchAllDFS tgt m = foldr go []
+  where
+    go (MatchClause pat f) acc =
+      let results = processMStatesAllDFS [MState HNil (MCons (MAtom pat m tgt) MNil)] in
+      map f results ++ acc
 
 -- | @matchDFS@ is much similar to @match@ but traverses a search tree for pattern matching in depth-first order.
+{-# INLINE matchDFS #-}
 matchDFS :: (Matcher m a) => a -> m -> [MatchClause a m b] -> b
 matchDFS tgt m cs = head $ matchAllDFS tgt m cs
 
@@ -49,23 +55,15 @@
 
 processMStatesAll :: [[MState vs]] -> [HList vs]
 processMStatesAll [] = []
-processMStatesAll streams =
-  case extractMatches $ concatMap processMStates streams of
-    ([], streams') -> processMStatesAll streams'
-    (results, streams') -> results ++ processMStatesAll streams'
-
-extractMatches :: [[MState vs]] -> ([HList vs], [[MState vs]])
-extractMatches = extractMatches' ([], [])
- where
-   extractMatches' :: ([HList vs], [[MState vs]]) -> [[MState vs]] -> ([HList vs], [[MState vs]])
-   extractMatches' (xs, ys) [] = (reverse xs,  reverse ys) -- These calls of the reverse function are very important for performance.
-   extractMatches' (xs, ys) ((MState rs MNil:[]):rest) = extractMatches' (rs:xs, ys) rest
-   extractMatches' (xs, ys) (stream:rest) = extractMatches' (xs, stream:ys) rest
-
-processMStates :: [MState vs] -> [[MState vs]]
-processMStates []          = []
-processMStates (mstate:ms) = [processMState mstate, ms]
+processMStatesAll streams = results ++ processMStatesAll streams'
+  where
+    (results, streams') = foldr processMStates ([], []) streams
+    processMStates :: [MState vs] -> ([HList vs], [[MState vs]]) -> ([HList vs], [[MState vs]])
+    processMStates [] (results, acc) = (results, acc)
+    processMStates (MState rs MNil:ms) (results, acc) = processMStates ms (rs:results, acc)
+    processMStates (mstate:ms) (results, acc) = (results, processMState mstate:ms:acc)
 
+{-# INLINE processMState #-}
 processMState :: MState vs -> [MState vs]
 processMState (MState rs (MCons (MAtom pat m tgt) atoms)) =
   case pat of
@@ -82,16 +80,19 @@
     OrPat p1 p2 ->
       [MState rs (MCons (MAtom p1 m tgt) atoms), MState rs (MCons (MAtom p2 m tgt) atoms)]
     NotPat p ->
-      [MState rs atoms | null $ processMStatesAll [[MState rs $ MCons (MAtom p m tgt) MNil]]]
+      [MState rs atoms | null $ processMStatesAllDFS [MState rs $ MCons (MAtom p m tgt) MNil]]
     PredicatePat f -> [MState rs atoms | f rs tgt]
 processMState (MState rs MNil) = undefined -- or [MState rs MNil] -- TODO: shold not reach here but reaches here.
 
+{-# INLINE patVarProof #-}
 patVarProof :: HList xs -> HList '[a] -> MList (xs :++: '[a]) ys -> ((xs :++: '[a]) :++: ys) :~: (xs :++: ('[a] :++: ys))
 patVarProof HNil _ _ = Refl
 patVarProof (HCons _ xs) ys zs = unsafeCoerce Refl -- Todo: Write proof.
 
+{-# INLINE andPatProof #-}
 andPatProof :: MAtom ctx vs -> MAtom (ctx :++: vs) vs' -> MList (ctx :++: vs :++: vs') ys -> (ctx :++: ((vs :++: vs') :++: ys)) :~: (ctx :++: (vs :++: (vs' :++: ys)))
 andPatProof _ _ _ = unsafeCoerce Refl -- Todo: Write proof.
 
+{-# INLINE assocProof #-}
 assocProof :: MAtom ctx vs -> MAtom (ctx :++: vs) vs' -> (ctx :++: (vs :++: vs')) :~: ((ctx :++: vs) :++: vs')
 assocProof _ _ = unsafeCoerce Refl -- Todo: Write proof.
diff --git a/src/Control/Egison/Matcher.hs b/src/Control/Egison/Matcher.hs
--- a/src/Control/Egison/Matcher.hs
+++ b/src/Control/Egison/Matcher.hs
@@ -93,9 +93,9 @@
 instance (Matcher m a, Eq a, ValuePat m a) => ValuePat (List m) [a] where
   valuePat f = Pattern (\ctx (List m) tgt ->
                             match (f ctx, tgt) (Pair (List m) (List m)) $
-                              [[mc| pair nil nil => [MNil] |],
-                               [mc| pair (cons $x $xs) (cons #x #xs) => [MNil] |],
-                               [mc| Wildcard => [] |]])
+                              [[mc| ([], []) -> [MNil] |],
+                               [mc| (($x : $xs), (#x : #xs)) -> [MNil] |],
+                               [mc| _ -> [] |]])
 
 instance Matcher m a => CollectionPat (List m) [a] where
   nil = Pattern (\_ _ t -> [MNil | null t])
@@ -118,16 +118,16 @@
 instance (Matcher m a, Eq a, ValuePat m a) => ValuePat (Multiset m) [a] where
   valuePat f = Pattern (\ctx (Multiset m) tgt ->
                             match (f ctx, tgt) (Pair (List m) (Multiset m)) $
-                              [[mc| pair nil nil => [MNil] |],
-                               [mc| pair (cons $x $xs) (cons #x #xs) => [MNil] |],
-                               [mc| Wildcard => [] |]])
+                              [[mc| ([], []) -> [MNil] |],
+                               [mc| (($x : $xs), (#x : #xs)) -> [MNil] |],
+                               [mc| _ -> [] |]])
 
 instance (Matcher m a) => CollectionPat (Multiset m) [a] where
   nil = Pattern (\_ _ tgt -> [MNil | null tgt])
   -- | The @cons@ pattern for a multiset decomposes a collection into an arbitrary element and the rest elements.
   cons p Wildcard = Pattern (\_ (Multiset m) tgt -> map (\x -> oneMAtom (MAtom p m x)) tgt)
   cons p1 p2 = Pattern (\_ (Multiset m) tgt -> map (\(x, xs) -> twoMAtoms (MAtom p1 m x) (MAtom p2 (Multiset m) xs))
-                                                   (matchAll tgt (List m) [[mc| join $hs (cons $x $ts) => (x, hs ++ ts) |]]))
+                                                   (matchAll tgt (List m) [[mc| $hs ++ $x : $ts -> (x, hs ++ ts) |]]))
   join p1 p2 = undefined
 
 -- | A matcher for a set. Both the order and the repetition of elements are ignored.
@@ -141,5 +141,5 @@
   nil = Pattern (\_ _ tgt -> [MNil | null tgt])
   cons p1 p2 = Pattern (\_ (Set m) tgt ->
                   map (\x -> twoMAtoms (MAtom p1 m x) (MAtom p2 (Set m) tgt))
-                      (matchAll tgt (List m) [[mc| join Wildcard (cons $x Wildcard) => x |]]))
+                      (matchAll tgt (List m) [[mc| _ ++ $x : _ -> x |]]))
   join p1 p2 = undefined
diff --git a/src/Control/Egison/QQ.hs b/src/Control/Egison/QQ.hs
--- a/src/Control/Egison/QQ.hs
+++ b/src/Control/Egison/QQ.hs
@@ -1,19 +1,66 @@
 -- | Quasiquotation for rewriting a match clause.
 
-module Control.Egison.QQ (
-  mc,
-  ) where
+module Control.Egison.QQ
+  ( mc
+  )
+where
 
 import           Control.Egison.Core
-import           Data.List
-import           Data.List.Split
-import           Data.Map                   (Map)
-import           Data.Maybe                 (fromMaybe)
-import           Language.Haskell.Meta
-import           Language.Haskell.TH        hiding (match)
-import           Language.Haskell.TH.Quote
-import           Language.Haskell.TH.Syntax
-import           Text.Regex
+import           Control.Monad                  ( (<=<) )
+import           Control.Monad.State            ( runStateT
+                                                , MonadState(..)
+                                                , modify
+                                                , lift
+                                                )
+import           Text.Read                      ( readMaybe )
+import           Data.Maybe                     ( mapMaybe )
+import           Data.List                      ( foldl' )
+import           Data.Functor.Foldable          ( Recursive
+                                                , Base
+                                                , cata
+                                                )
+import           Language.Haskell.TH            ( Q
+                                                , Loc(..)
+                                                , Exp(..)
+                                                , Pat(..)
+                                                , Lit(..)
+                                                , Name
+                                                , location
+                                                , extsEnabled
+                                                , mkName
+                                                , pprint
+                                                )
+import           Language.Haskell.TH.Quote      ( QuasiQuoter(..) )
+import qualified Language.Haskell.TH           as TH
+                                                ( Extension(..) )
+import           Language.Haskell.Exts.Extension
+                                                ( Extension(EnableExtension) )
+import           Language.Haskell.Exts.Parser   ( ParseResult(..)
+                                                , defaultParseMode
+                                                , parseExpWithMode
+                                                )
+import qualified Language.Haskell.Exts.Extension
+                                               as Exts
+                                                ( KnownExtension(..) )
+import qualified Language.Haskell.Exts.Parser  as Exts
+                                                ( ParseMode(..) )
+import           Language.Haskell.Meta.Syntax.Translate
+                                                ( toExp )
+import qualified Language.Egison.Syntax.Pattern
+                                               as Pat
+                                                ( Expr
+                                                , ExprF(..)
+                                                )
+import qualified Language.Egison.Parser.Pattern
+                                               as Pat
+                                                ( parseNonGreedy )
+import           Language.Egison.Parser.Pattern ( Fixity(..)
+                                                , ParseFixity(..)
+                                                , Associativity(..)
+                                                , Precedence(..)
+                                                )
+import           Language.Egison.Parser.Pattern.Mode.Haskell.TH
+                                                ( ParseMode(..) )
 
 -- | A quasiquoter for rewriting a match clause.
 -- This quasiquoter is useful for generating a 'MatchClause' in user-friendly syntax.
@@ -55,7 +102,7 @@
 -- 
 -- A match clause that contains an and-pattern
 -- 
--- > [mc| (& (cons _ _) $x) => x |]
+-- > [mc| (cons _ _) & $x => x |]
 -- 
 -- is rewritten to
 -- 
@@ -66,100 +113,130 @@
 -- 
 -- A match clause that contains an or-pattern
 -- 
--- > [mc| (| nil (cons _ _)) => "Matched" |]
+-- > [mc| nil | (cons _ _) => "Matched" |]
 -- 
 -- is rewritten to
 -- 
 -- > MatchClause (OrPat nil (cons Wildcard Wildcard))
 -- >             (\HNil -> "Matched")
+--
+-- === Collection patterns
+--
+-- A collection pattern
+--
+-- > [p1, p2, ..., pn]
+--
+-- is desugared into
+--
+-- > p1 : p2 : ... : pn : nil
+--
+-- === Cons patterns
+--
+-- A pattern with special collection pattern operator @:@
+--
+-- > p1 : p2
+--
+-- is parsed as
+--
+-- > p1 `cons` p2
+--
+-- === Join patterns
+--
+-- A pattern with special collection pattern operator @++@
+--
+-- > p1 ++ p2
+--
+-- is parsed as
+--
+-- > p1 `join` p2
 mc :: QuasiQuoter
-mc = QuasiQuoter { quoteExp = \s -> do
-                      let [pat, exp] = splitOn "=>" s
-                      e1 <- case parseExp (changeNotPat (changeOrPat (changeAndPat (changeValuePat (changePatVar (changeWildcard pat)))))) of
-                              Left _ -> fail "Could not parse pattern expression."
-                              Right exp -> return exp
-                      e2 <- case parseExp exp of
-                                 Left _ -> fail "Could not parse expression."
-                                 Right exp -> return exp
-                      mcChange e1 e2
-                  , quotePat = undefined
-                  , quoteType = undefined
-                  , quoteDec = undefined }
+mc = QuasiQuoter { quoteExp  = compile
+                 , quotePat  = undefined
+                 , quoteType = undefined
+                 , quoteDec  = undefined
+                 }
 
-changeWildcard :: String -> String
-changeWildcard pat = subRegex (mkRegex " _") pat " Wildcard"
 
-changePatVar :: String -> String
-changePatVar pat = subRegex (mkRegex "\\$([a-zA-Z0-9]+)") pat "(PatVar \"\\1\")"
-
-changeValuePat :: String -> String
-changeValuePat pat = subRegex (mkRegex "\\#(\\([^)]+\\)|\\[[^)]+\\]|[a-zA-Z0-9]+)") pat "(valuePat \\1)"
+listFixities :: [ParseFixity Name String]
+listFixities =
+  [ ParseFixity (Fixity AssocRight (Precedence 5) (mkName "join")) $ parser "++"
+  , ParseFixity (Fixity AssocRight (Precedence 5) (mkName "cons")) $ parser ":"
+  ]
+ where
+  parser symbol content | symbol == content = Right ()
+                        | otherwise = Left $ show symbol ++ "is expected"
 
-changeAndPat :: String -> String
-changeAndPat pat = subRegex (mkRegex "\\(\\&") pat "(AndPat"
+parseMode :: Q Exts.ParseMode
+parseMode = do
+  Loc { loc_filename } <- location
+  extensions <- mapMaybe (fmap EnableExtension . convertExt) <$> extsEnabled
+  pure defaultParseMode { Exts.parseFilename = loc_filename, Exts.extensions }
+ where
+  convertExt :: TH.Extension -> Maybe Exts.KnownExtension
+  convertExt TH.TemplateHaskellQuotes = Just Exts.TemplateHaskell  -- haskell-suite/haskell-src-exts#357
+  convertExt ext                      = readMaybe $ show ext
 
-changeOrPat :: String -> String
-changeOrPat pat = subRegex (mkRegex "\\(\\|") pat "(OrPat"
+parseExp :: Exts.ParseMode -> String -> Q Exp
+parseExp mode content = case parseExpWithMode mode content of
+  ParseOk x       -> pure $ toExp x
+  ParseFailed _ e -> fail e
 
-changeNotPat :: String -> String
-changeNotPat pat = subRegex (mkRegex "\\(not ") pat "(NotPat "
+compile :: String -> Q Exp
+compile content = do
+  mode        <- parseMode
+  (pat, rest) <- parsePatternExpr mode content
+  bodySource  <- takeBody rest
+  body        <- parseExp mode bodySource
+  compilePattern pat body
+ where
+  takeBody ('-' : '>' : xs) = pure xs
+  takeBody xs               = fail $ "\"->\" is expected, but found " ++ show xs
 
-mcChange :: Exp -> Exp -> Q Exp
-mcChange pat expr = do
-  let (vars, xs) = extractPatVars [pat] []
-  [| (MatchClause $(fst <$> changePat pat (map (`take` vars) xs)) $(changeExp vars expr)) |]
+parsePatternExpr
+  :: Exts.ParseMode -> String -> Q (Pat.Expr Name Name Exp, String)
+parsePatternExpr haskellMode content = case Pat.parseNonGreedy mode content of
+  Left  e -> fail $ show e
+  Right x -> pure x
+  where mode = ParseMode { haskellMode, fixities = Just listFixities }
 
--- extract patvars from pattern
-extractPatVars :: [Exp] -> [String] -> ([String], [Int])
-extractPatVars [] vars = (vars, [])
-extractPatVars (ParensE x:xs) vars = extractPatVars (x:xs) vars
-extractPatVars (AppE (ConE name) p:xs) vars
-  | nameBase name == "PatVar" = case p of (LitE (StringL s)) -> extractPatVars xs (vars ++ [s])
-  | nameBase name == "PredicatePat" = let (vs, ns) = extractPatVars xs vars in (vs, length vars:ns)
-  | nameBase name == "LaterPat" =
-      let (vs1, ns1) = extractPatVars xs vars in
-      let (vs2, ns2) = extractPatVars [p] vs1 in (vs2, ns2 ++ ns1)
-  | otherwise = extractPatVars (p:xs) vars
-extractPatVars (AppE (VarE name) p:xs) vars
-  | nameBase name == "valuePat" = let (vs, ns) = extractPatVars xs vars in (vs, length vars:ns)
-  | otherwise = extractPatVars (p:xs) vars
-extractPatVars (AppE a b:xs) vars = extractPatVars (a:b:xs) vars
-extractPatVars (SigE x typ:xs) vs = extractPatVars (x:xs) vs
-extractPatVars (_:xs) vars = extractPatVars xs vars
+compilePattern :: Pat.Expr Name Name Exp -> Exp -> Q Exp
+compilePattern pat body = do
+  (clauseExp, bindings) <- runStateT (cataM go pat) []
+  let bodyExp = bsFun bindings body
+  pure $ AppE (AppE (ConE 'Control.Egison.Core.MatchClause) clauseExp) bodyExp
+ where
+  bsFun bs = LamE [toHListPat bs]
+  go Pat.WildcardF     = pure $ ConE 'Control.Egison.Core.Wildcard
+  go (Pat.VariableF v) = do
+    modify (<> [v])
+    pure . AppE (ConE 'Control.Egison.Core.PatVar) . LitE . StringL $ pprint v
+  go (Pat.ValueF e) = do
+    bs <- get
+    pure . AppE (VarE $ mkName "valuePat") $ bsFun bs e
+  go (Pat.PredicateF e) = do
+    bs <- get
+    pure . AppE (ConE 'Control.Egison.Core.PredicatePat) $ bsFun bs e
+  go (Pat.AndF e1 e2) =
+    pure $ AppE (AppE (ConE 'Control.Egison.Core.AndPat) e1) e2
+  go (Pat.OrF e1 e2) =
+    pure $ AppE (AppE (ConE 'Control.Egison.Core.OrPat) e1) e2
+  go (Pat.NotF e1) = pure $ AppE (ConE 'Control.Egison.Core.NotPat) e1
+  go (Pat.TupleF [e1, e2]) = pure $ AppE (AppE (VarE $ mkName "pair") e1) e2
+  go (Pat.TupleF _) = lift $ fail "tuples other than pairs are not supported"
+  go (Pat.CollectionF es) = pure $ toNilCons es
+  go (Pat.InfixF n e1 e2) = pure . ParensE $ UInfixE e1 (VarE n) e2
+  go (Pat.PatternF n es) = pure $ foldl' AppE (VarE n) es
 
--- change ValuePat e to \(HCons x HNil) -> e
--- change PredicatePat (\x -> e) to \(HCons x HNil) -> (\x -> e)
-changePat :: Exp -> [[String]] -> Q (Exp, [[String]])
-changePat e@(AppE (ConE name) p) vs
-  | nameBase name == "PredicatePat" = do
-      let (vars:varss) = vs
-      (, varss) <$> appE (conE 'PredicatePat) (changeExp vars p)
-  | otherwise = do
-      (e', vs') <- changePat p vs
-      (, vs') <$> appE (conE name) (return e')
-changePat e@(AppE (VarE name) p) vs
-  | nameBase name == "valuePat" = do
-      let (vars:varss) = vs
-      (, varss) <$> appE (varE name) (changeExp vars p)
-  | otherwise = do
-      (e', vs') <- changePat p vs
-      (, vs') <$> appE (varE name) (return e')
-changePat (AppE e1 e2) vs = do
-  (e1', vs') <- changePat e1 vs
-  (e2', vs'') <- changePat e2 vs'
-  (, vs'') <$> appE (return e1') (return e2')
-changePat (ParensE x) vs = changePat x vs
-changePat (SigE x typ) vs = changePat x vs
-changePat e vs = return (e, vs)
+toHListPat :: [Name] -> Pat
+toHListPat = foldr go $ ConP 'HNil [] where go x a = ConP 'HCons [VarP x, a]
 
--- change e to \(HCons x HNil) -> e
-changeExp :: [String] -> Exp -> Q Exp
-changeExp vars expr = do
-  vars' <- mapM newName vars
-  vars'' <- mapM (\s -> newName $ s ++ "'") vars
-  return $ LamE [f vars'] expr
+toNilCons :: [Exp] -> Exp
+toNilCons = foldr go . VarE $ mkName "nil"
+  where go e = AppE (AppE (VarE $ mkName "cons") e)
 
--- \[x, y] -> HCons x (HCons y HNil)
-f :: [Name] -> Pat
-f []     = ConP 'HNil []
-f (x:xs) = InfixP (VarP x) 'HCons $ f xs
+cataM
+  :: (Recursive t, Traversable (Base t), Monad m)
+  => (Base t a -> m a)
+  -> t
+  -> m a
+cataM alg = cata (alg <=< sequence)
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -10,99 +10,99 @@
 
 pmap :: (a -> b) -> [a] -> [b]
 pmap f xs = matchAll xs (List Something)
-             [[mc| join _ (cons $x _) => f x |]]
+             [[mc| _ ++ $x : _ -> f x |]]
 
 pmConcat :: [[a]] -> [a]
 pmConcat xss = matchAll xss (Multiset (Multiset Something))
-                 [[mc| cons (cons $x _) _ => x |]]
+                 [[mc| ($x : _) : _ -> x |]]
 
 pmUniq :: (Eq a) => [a] -> [a]
 pmUniq xs = matchAll xs (List Eql)
-               [[mc| join _ (cons $x (not (join _ (cons #x _)))) => x |]]
+               [[mc| _ ++ $x : !(_ ++ #x : _) -> x |]]
 
 pmIntersect :: (Eq a) => [a] -> [a] -> [a]
 pmIntersect xs ys = matchAll (xs, ys) (Pair (Multiset Eql) (Multiset Eql))
-                      [[mc| pair (cons $x _) (cons #x _) => x |]]
+                      [[mc| (($x : _), (#x : _)) -> x |]]
 
 pmDiff :: (Eq a) => [a] -> [a] -> [a]
 pmDiff xs ys = matchAll (xs, ys) (Pair (Multiset Eql) (Multiset Eql))
-                 [[mc| pair (cons $x _) (not (cons #x _)) => x |]]
+                 [[mc| (($x : _), !(#x : _)) -> x |]]
 
 spec :: Spec
 spec = do
   describe "list and multiset matchers" $ do
     it "cons pattern for list" $
-      matchAll [1,2,3] (List Integer) [[mc| cons $x $xs => (x, xs) |]]
+      matchAll [1,2,3] (List Integer) [[mc| $x : $xs -> (x, xs) |]]
       `shouldBe` [(1, [2,3])]
 
     it "multiset cons pattern" $
-      matchAll [1,2,3] (Multiset Integer) [[mc| cons $x $xs => (x, xs) |]]
+      matchAll [1,2,3] (Multiset Integer) [[mc| $x : $xs -> (x, xs) |]]
       `shouldBe` [(1,[2,3]),(2,[1,3]),(3,[1,2])]
 
     it "join pattern for list matcher" $ length (
       matchAll [1..5] (List Integer)
-        [[mc| join $xs $ys => (xs, ys) |]])
+        [[mc| $xs ++ $ys -> (xs, ys) |]])
       `shouldBe` 6
 
     it "value pattern for list matcher (1)" $
       match [1,2,3] (List Integer)
-        [[mc| #[1,2,3] => "Matched" |],
-         [mc| _ => "Not matched" |]]
+        [[mc| #[1,2,3] -> "Matched" |],
+         [mc| _ -> "Not matched" |]]
       `shouldBe` "Matched"
 
     it "value pattern for list matcher (2)" $
       match [1,2,3] (List Integer)
-        [[mc| #[2,1,3] => "Matched" |],
-         [mc| _ => "Not matched" |]]
+        [[mc| #[2,1,3] -> "Matched" |],
+         [mc| _ -> "Not matched" |]]
       `shouldBe` "Not matched"
 
     it "value pattern for multiset matcher" $
       match [1,2,3] (Multiset Integer)
-        [[mc| #[2,1,3] => "Matched" |],
-         [mc| _ => "Not matched" |]]
+        [[mc| #[2,1,3] -> "Matched" |],
+         [mc| _ -> "Not matched" |]]
       `shouldBe` "Matched"
 
 --    it "test" $
 --      match 1 (List Integer)
---        [[mc| $x => "Matched" |]]
+--        [[mc| $x -> "Matched" |]]
 --      `shouldBe` "Matched"
 
   describe "match-all with infinitely many results" $ do
     it "Check the order of pattern-matching results (multiset bfs) " $
       take 10 (matchAll [1..] (Multiset Integer)
-                 [[mc| cons $x (cons $y _) => (x, y) |]])
+                 [[mc| $x : $y : _ -> (x, y) |]])
       `shouldBe` [(1,2),(1,3),(2,1),(1,4),(2,3),(3,1),(1,5),(2,4),(3,2),(4,1)]
 
     it "Check the order of pattern-matching results (set bfs)" $
       take 10 (matchAll [1..] (Set Integer)
-                 [[mc| cons $x (cons $y _) => (x, y) |]])
+                 [[mc| $x : $y : _ -> (x, y) |]])
       `shouldBe` [(1,1),(1,2),(2,1),(1,3),(2,2),(3,1),(1,4),(2,3),(3,2),(4,1)]
 
     it "Check the order of pattern-matching results (set dfs)" $
       take 10 (matchAllDFS [1..] (Set Integer)
-                 [[mc| cons $x (cons $y _) => (x, y) |]])
+                 [[mc| $x : $y : _ -> (x, y) |]])
       `shouldBe` [(1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(1,8),(1,9),(1,10)]
 
   describe "built-in pattern constructs" $ do
     it "Predicate patterns" $
       matchAll [1..10] (Multiset Integer)
-        [[mc| cons (& (PredicatePat (\x -> mod x 2 == 0)) $x) _ => x |]]
+        [[mc| (?(\x -> mod x 2 == 0) & $x) : _ -> x |]]
       `shouldBe` [2,4,6,8,10]
 
   describe "patterns for prime numbers" $ do
     it "twin primes (p, p+2)" $
       take 10 (matchAll primes (List Integer)
-                 [[mc| join _ (cons $p (cons #(p+2) _)) => (p, p+2) |]])
+                 [[mc| _ ++ $p : #(p+2) : _ -> (p, p+2) |]])
       `shouldBe` [(3,5),(5,7),(11,13),(17,19),(29,31),(41,43),(59,61),(71,73),(101,103),(107,109)]
 
     it "prime pairs whose form is (p, p+6) -- pattern matching with infinitely many results" $
       take 10 (matchAll primes (List Integer)
-                 [[mc| join _ (cons $p (join _ (cons #(p+6) _))) => (p, p+6) |]])
+                 [[mc| _ ++ $p : _ ++ #(p+6) : _ -> (p, p+6) |]])
       `shouldBe` [(5,11),(7,13),(11,17),(13,19),(17,23),(23,29),(31,37),(37,43),(41,47),(47,53)]
 
     it "prime triplets -- and-patterns, or-patterns, and not-patterns" $
       take 10 (matchAll primes (List Integer)
-                 [[mc| join _ (cons $p (cons (& (| #(p+2) #(p+4)) $m) (cons #(p+6) _))) => (p, m, p+6) |]])
+                 [[mc| _ ++ $p : ($m & (#(p+2) | #(p+4))) : #(p+6) : _ -> (p, m, p+6) |]])
       `shouldBe` [(5,7,11),(7,11,13),(11,13,17),(13,17,19),(17,19,23),(37,41,43),(41,43,47),(67,71,73),(97,101,103),(101,103,107)]
 
   describe "Basic list processing functions" $ do
