diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -9,3 +9,9 @@
 * Moved tests and benchmarks into a subproject, which will be easier later down the line.
 * Removed useless `dump-core` flag (only used by test and bench, not by the library).
 * Fleshed out README properly!
+
+## 0.1.1.0  -- 2021-06-10
+
+* Added `IF_S`, `LAM_S` and `LET_S` to `Defunc`, which can be used with overloaded syntax
+* Admin: Removed `idioms-plugin` and `lift-plugin` from the test suite, depending on `parsley-garnish` instead
+* Fixed building with GHC 9
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,11 +1,11 @@
-# Parsley ![GitHub Workflow Status](https://img.shields.io/github/workflow/status/j-mie6/ParsleyHaskell/CI) ![GitHub release](https://img.shields.io/github/v/release/j-mie6/ParsleyHaskell?include_prereleases&sort=semver) [![GitHub license](https://img.shields.io/github/license/j-mie6/ParsleyHaskell.svg)](https://github.com/j-mie6/ParsleyHakell/blob/master/LICENSE)
+# Parsley ![GitHub Workflow Status](https://img.shields.io/github/workflow/status/j-mie6/ParsleyHaskell/CI) ![GitHub release](https://img.shields.io/github/v/release/j-mie6/ParsleyHaskell) [![GitHub license](https://img.shields.io/github/license/j-mie6/ParsleyHaskell.svg)](https://github.com/j-mie6/ParsleyHaskell/blob/master/LICENSE) ![GitHub commits since latest release (by SemVer)](https://img.shields.io/github/commits-since/j-mie6/ParsleyHaskell/latest)
 
 ## What is Parsley?
 Parsley is a very fast parser combinator library that outperforms the other libraries in both the
 parsec family, as well as Happy. To make this possible, it makes use of Typed Template Haskell
 to generate the code for the parsers.
 
-## How do I use it? ![Hackage Version](https://img.shields.io/hackage/v/parsley)
+## How do I use it? [![Hackage Version](https://img.shields.io/hackage/v/parsley)](https://hackage.haskell.org/package/parsley) ![Dependent repos (via libraries.io)](https://img.shields.io/librariesio/dependent-repos/hackage/parsley)
 Parsley is distributed on Hackage, and can be added by depending on the package `parsley`.
 
 The version policy adheres to the regular Haskell PVP, but the two major versions are distinguished
@@ -51,9 +51,10 @@
 char c = satisfy (WQ (== c) [||(== c)||])
 ```
 
-Using `WQ` explicitly like this can get annoying, which is what the `lift-plugin` and the
-`idioms-plugin` are both for: versions compatible with Parsley can be found on my GitHub, and the
-`cabal.project` in this repo shows how these should be installed until they are properly released.
+Using `WQ` explicitly like this can get annoying, which is what the `parsley-garnish` package is for!
+Currently, the garnish provides one plugin called `OverloadedQuotes`, which replaces the behaviour of
+the default _Untyped_ Template Haskell quotes in a file so that they produce one of `WQ` or `Defunc`.
+See the `Parsley.OverloadedQuotesPlugin` module in the [`parsley-garnish`](https://hackage.haskell.org/package/parsley-garnish) package for more information.
 
 ## How does it work?
 In short, Parsley represents all parsers as Abstract Syntax Trees (ASTs). The representation of the
@@ -70,3 +71,11 @@
 
 ## References
 * This work spawned a paper at ICFP 2020: [**Staged Selective Parser Combinators**](https://dl.acm.org/doi/10.1145/3409002)
+
+### Talks
+For talks on how writing parsers changes when using Parsley see either of these:
+* [*Garnishing Parsec with Parsley*](https://www.youtube.com/watch?v=tJcyY9L2z84) - Berlin Functional Programming Group, January 2021
+* [*Exploring Parsley: Working with Staged Selective Parsers*](https://www.youtube.com/watch?v=Zhu-cPY1eac) - MuniHac 2020
+
+For the technical overview of how Parsley works:
+* [*Staged Selective Parser Combinators*](https://www.youtube.com/watch?v=lH65PvRgm8M) - ICFP 2020
diff --git a/parsley.cabal b/parsley.cabal
--- a/parsley.cabal
+++ b/parsley.cabal
@@ -5,7 +5,7 @@
 --                   | +------- breaking internal API changes
 --                   | | +----- non-breaking API additions
 --                   | | | +--- code changes with no API change
-version:             0.1.0.1
+version:             0.1.1.0
 synopsis:            A fast parser combinator library backed by Typed Template Haskell
 description:         Parsley is a staged selective parser combinator library, which means
                      it does not support monadic operations, and relies on Typed Template
@@ -29,7 +29,7 @@
 bug-reports:         https://github.com/j-mie6/ParsleyHaskell/issues
 license:             BSD-3-Clause
 license-file:        LICENSE
-author:              Jamie Willis
+author:              Jamie Willis, Parsley Contributors
 maintainer:          Jamie Willis <j.willis19@imperial.ac.uk>
 category:            Parsing
 build-type:          Simple
@@ -122,7 +122,7 @@
                        text                 >= 1.2.3   && < 1.3,
                        -- Not sure about this one, 0.11.0.0 introduced a type synonym for PS, so it _should_ work
                        bytestring           >= 0.10.8  && < 0.12
-  build-tool-depends:  cpphs:cpphs          >= 1.19
+  build-tool-depends:  cpphs:cpphs          >= 1.18.8  && < 1.21
   hs-source-dirs:      src/ghc
   if impl(ghc >= 8.10)
     hs-source-dirs:    src/ghc-8.10+
diff --git a/src/ghc-8.10+/Parsley/Internal/Backend/Machine/InputRep.hs b/src/ghc-8.10+/Parsley/Internal/Backend/Machine/InputRep.hs
--- a/src/ghc-8.10+/Parsley/Internal/Backend/Machine/InputRep.hs
+++ b/src/ghc-8.10+/Parsley/Internal/Backend/Machine/InputRep.hs
@@ -3,9 +3,9 @@
              UnboxedTuples,
              StandaloneKindSignatures #-}
 module Parsley.Internal.Backend.Machine.InputRep (
-    Rep,
+    Rep, RepKind,
     intSame, intLess, min#, max#,
-    offWith, offWithSame, offWithShiftRight,
+    OffWith, offWith, offWithSame, offWithShiftRight,
     --OffWithStreamAnd(..),
     UnpackedLazyByteString, emptyUnpackedLazyByteString,
     Stream, dropStream,
diff --git a/src/ghc/Parsley/Combinator.hs b/src/ghc/Parsley/Combinator.hs
--- a/src/ghc/Parsley/Combinator.hs
+++ b/src/ghc/Parsley/Combinator.hs
@@ -103,7 +103,7 @@
 @since 0.1.0.0
 -}
 item :: Parser Char
-item = satisfy (APP_H CONST ((makeQ True [||True||])))
+item = satisfy (APP_H CONST (LIFTED True))
 
 -- Composite Combinators
 {-|
diff --git a/src/ghc/Parsley/Internal/Backend/InstructionAnalyser.hs b/src/ghc/Parsley/Internal/Backend/InstructionAnalyser.hs
--- a/src/ghc/Parsley/Internal/Backend/InstructionAnalyser.hs
+++ b/src/ghc/Parsley/Internal/Backend/InstructionAnalyser.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE MultiParamTypeClasses,
              TypeFamilies,
              UndecidableInstances #-}
-module Parsley.Internal.Backend.InstructionAnalyser (coinsNeeded, relevancy) where
+module Parsley.Internal.Backend.InstructionAnalyser (coinsNeeded, relevancy, Length) where
 
 import Data.Kind                        (Type)
 import Parsley.Internal.Backend.Machine (Instr(..), MetaInstr(..))
diff --git a/src/ghc/Parsley/Internal/Common/Fresh.hs b/src/ghc/Parsley/Internal/Common/Fresh.hs
--- a/src/ghc/Parsley/Internal/Common/Fresh.hs
+++ b/src/ghc/Parsley/Internal/Common/Fresh.hs
@@ -7,7 +7,8 @@
     runFreshT, runFresh,
     evalFreshT, evalFresh,
     execFreshT, execFresh,
-    MonadFresh(..), construct, mapVFreshT
+    MonadFresh(..), construct, mapVFreshT,
+    RunFreshT
   ) where
 
 import Control.Applicative        (liftA2)
diff --git a/src/ghc/Parsley/Internal/Common/Utils.hs b/src/ghc/Parsley/Internal/Common/Utils.hs
--- a/src/ghc/Parsley/Internal/Common/Utils.hs
+++ b/src/ghc/Parsley/Internal/Common/Utils.hs
@@ -25,7 +25,7 @@
 
 @since 0.1.0.0
 -}
-#if __GLASGOW_HASKELL__ == 810
+#if __GLASGOW_HASKELL__ >= 810
 type Code :: forall (r :: RuntimeRep). TYPE r -> Type
 #endif
 #if __GLASGOW_HASKELL__ < 900
diff --git a/src/ghc/Parsley/Internal/Core/Defunc.hs b/src/ghc/Parsley/Internal/Core/Defunc.hs
--- a/src/ghc/Parsley/Internal/Core/Defunc.hs
+++ b/src/ghc/Parsley/Internal/Core/Defunc.hs
@@ -37,23 +37,47 @@
   -- | Wraps up any value of type `WQ`
   BLACK   :: WQ a -> Defunc a
 
+  -- Syntax constructors
+  {-|
+  Represents the regular Haskell @if@ syntax
+
+  @since 0.1.1.0
+  -}
+  IF_S    :: Defunc Bool -> Defunc a -> Defunc a -> Defunc a
+  {-|
+  Represents a Haskell lambda abstraction
+
+  @since 0.1.1.0
+  -}
+  LAM_S   :: (Defunc a -> Defunc b) -> Defunc (a -> b)
+  {-|
+  Represents a Haskell let binding
+
+  @since 0.1.1.0
+  -}
+  LET_S   :: Defunc a -> (Defunc a -> Defunc b) -> Defunc b
+
 {-|
 This instance is used to manipulate values of `Defunc`.
 
 @since 0.1.0.0
 -}
 instance Quapplicative Defunc where
-  makeQ x qx       = BLACK (makeQ x qx)
-  _val ID          = id
-  _val COMPOSE     = (.)
-  _val FLIP        = flip
-  _val (APP_H f x) = (_val f) (_val x)
-  _val (LIFTED x)  = x
-  _val (EQ_H x)    = ((_val x) ==)
-  _val CONS        = (:)
-  _val CONST       = const
-  _val EMPTY       = []
-  _val (BLACK f)   = _val f
+  makeQ x qx        = BLACK (makeQ x qx)
+  _val ID           = id
+  _val COMPOSE      = (.)
+  _val FLIP         = flip
+  _val (APP_H f x)  = (_val f) (_val x)
+  _val (LIFTED x)   = x
+  _val (EQ_H x)     = ((_val x) ==)
+  _val CONS         = (:)
+  _val CONST        = const
+  _val EMPTY        = []
+  _val (BLACK f)    = _val f
+  -- Syntax
+  _val (IF_S c t e) = if _val c then _val t else _val e
+  _val (LAM_S f)    = \x -> _val (f (makeQ x undefined))
+  _val (LET_S x f)  = let y = _val x in _val (f (makeQ y undefined))
   _code = genDefunc
   (>*<) = APP_H
 
@@ -90,19 +114,24 @@
 ap f x = APP_H f x
 
 genDefunc :: Defunc a -> Code a
-genDefunc ID              = [|| \x -> x ||]
-genDefunc COMPOSE         = [|| \f g x -> f (g x) ||]
-genDefunc FLIP            = [|| \f x y -> f y x ||]
-genDefunc (COMPOSE_H f g) = [|| \x -> $$(genDefunc1 (COMPOSE_H f g) [||x||]) ||]
-genDefunc CONST           = [|| \x _ -> x ||]
-genDefunc FLIP_CONST      = [|| \_ y -> y ||]
-genDefunc (FLIP_H f)      = [|| \x -> $$(genDefunc1 (FLIP_H f) [||x||]) ||]
-genDefunc (APP_H f x)     = genDefunc1 f (genDefunc x)
-genDefunc (LIFTED x)      = [|| x ||]
-genDefunc (EQ_H x)        = [|| \y -> $$(genDefunc1 (EQ_H x) [||y||]) ||]
-genDefunc CONS            = [|| \x xs -> x : xs ||]
-genDefunc EMPTY           = [|| [] ||]
-genDefunc (BLACK f)       = _code f
+genDefunc ID                        = [|| \x -> x ||]
+genDefunc COMPOSE                   = [|| \f g x -> f (g x) ||]
+genDefunc FLIP                      = [|| \f x y -> f y x ||]
+genDefunc (COMPOSE_H f g)           = [|| \x -> $$(genDefunc1 (COMPOSE_H f g) [||x||]) ||]
+genDefunc CONST                     = [|| \x _ -> x ||]
+genDefunc FLIP_CONST                = [|| \_ y -> y ||]
+genDefunc (FLIP_H f)                = [|| \x -> $$(genDefunc1 (FLIP_H f) [||x||]) ||]
+genDefunc (APP_H f x)               = genDefunc1 f (genDefunc x)
+genDefunc (LIFTED x)                = [|| x ||]
+genDefunc (EQ_H x)                  = [|| \y -> $$(genDefunc1 (EQ_H x) [||y||]) ||]
+genDefunc CONS                      = [|| \x xs -> x : xs ||]
+genDefunc EMPTY                     = [|| [] ||]
+genDefunc (IF_S (LIFTED True) t _)  = genDefunc t
+genDefunc (IF_S (LIFTED False) _ e) = genDefunc e
+genDefunc (IF_S c t e)              = [|| if $$(genDefunc c) then $$(genDefunc t) else $$(genDefunc e) ||]
+genDefunc (LAM_S f)                 = [|| \x -> $$(genDefunc1 (LAM_S f) [||x||]) ||]
+genDefunc (LET_S x f)               = [|| let y = $$(genDefunc x) in $$(genDefunc (f (makeQ undefined [||y||]))) ||]
+genDefunc (BLACK f)                 = _code f
 
 genDefunc1 :: Defunc (a -> b) -> Code a -> Code b
 genDefunc1 ID              qx = qx
@@ -115,6 +144,7 @@
 genDefunc1 FLIP_CONST      _  = genDefunc ID
 genDefunc1 (FLIP_H f)      qx = [|| \y -> $$(genDefunc2 (FLIP_H f) qx [||y||]) ||]
 genDefunc1 (EQ_H x)        qy = [|| $$(genDefunc x)  == $$qy ||]
+genDefunc1 (LAM_S f)       qx = genDefunc (f (makeQ undefined qx))
 genDefunc1 f               qx = [|| $$(genDefunc f) $$qx ||]
 
 genDefunc2 :: Defunc (a -> b -> c) -> Code a -> Code b -> Code c
@@ -126,7 +156,7 @@
 genDefunc2 FLIP_CONST      _  qy  = qy
 genDefunc2 (FLIP_H f)      qx qy  = genDefunc2 f qy qx
 genDefunc2 CONS            qx qxs = [|| $$qx : $$qxs ||]
-genDefunc2 f               qx qy  = [|| $$(genDefunc f) $$qx $$qy ||]
+genDefunc2 f               qx qy  = [|| $$(genDefunc1 f qx) $$qy ||]
 
 instance Show (Defunc a) where
   show COMPOSE = "(.)"
@@ -140,4 +170,6 @@
   show EMPTY = "[]"
   show CONS = "(:)"
   show CONST = "const"
+  show (IF_S c b e) = concat ["(if ", show c, " then ", show b, " else ", show e, ")"]
+  show (LAM_S _) = "f"
   show _ = "x"
diff --git a/src/ghc/Parsley/Internal/Frontend/Optimiser.hs b/src/ghc/Parsley/Internal/Frontend/Optimiser.hs
--- a/src/ghc/Parsley/Internal/Frontend/Optimiser.hs
+++ b/src/ghc/Parsley/Internal/Frontend/Optimiser.hs
@@ -129,7 +129,7 @@
 -- pure Right law: branch (pure (Right x)) p q          = q <*> pure x
 optimise (Branch (In (Pure (r@(_val -> Right x)))) _ q) = optimise (q :<*>: In (Pure (makeQ x qx))) where qx = [||case $$(_code r) of Right x -> x||]
 -- Generalised Identity law: branch b (pure f) (pure g) = either f g <$> b
-optimise (Branch b (In (Pure f)) (In (Pure g)))         = optimise ({-([either f g])-}makeQ (either (_val f) (_val g)) [||either $$(_code f) $$(_code g)||] :<$>: b)
+optimise (Branch b (In (Pure f)) (In (Pure g)))         = optimise (makeQ (either (_val f) (_val g)) [||either $$(_code f) $$(_code g)||] :<$>: b)
 -- Interchange law: branch (x *> y) p q                 = x *> branch y p q
 optimise (Branch (In (x :*>: y)) p q)                   = optimise (x :*>: optimise (Branch y p q))
 -- Negated Branch law: branch b p empty                 = branch (swapEither <$> b) empty p
diff --git a/src/ghc/Parsley/Precedence.hs b/src/ghc/Parsley/Precedence.hs
--- a/src/ghc/Parsley/Precedence.hs
+++ b/src/ghc/Parsley/Precedence.hs
@@ -68,7 +68,7 @@
                | Postfix [Parser (b -> b)]      (Defunc (a -> b)) -- ^ postfix unary operators
 
 {-|
-This class provides a way of working with the `Level` datatype without needing to
+This class provides a way of working with the t`Level` datatype without needing to
 provide wrappers, or not providing `Defunc` arguments.
 
 @since 0.1.0.0
diff --git a/src/ghc/Parsley/Selective.hs b/src/ghc/Parsley/Selective.hs
--- a/src/ghc/Parsley/Selective.hs
+++ b/src/ghc/Parsley/Selective.hs
@@ -27,7 +27,7 @@
 import Language.Haskell.TH.Syntax (Lift(..))
 import Parsley.Alternative        (empty)
 import Parsley.Applicative        (pure, (<$>), liftA2, unit, constp)
-import Parsley.Internal           (makeQ, Code, Parser, Defunc(ID, EQ_H), ParserOps, conditional, branch)
+import Parsley.Internal           (makeQ, Parser, Defunc(ID, EQ_H, IF_S, LAM_S, LET_S, APP_H), ParserOps, conditional, branch)
 
 {-|
 Similar to `branch`, except the given branch is only executed on a @Left@ returned.
@@ -49,12 +49,16 @@
 -}
 infixl 4 >??>
 (>??>) :: Parser a -> Parser (a -> Bool) -> Parser a
-px >??> pf = select (liftA2 (makeQ g qg) pf px) empty
+px >??> pf = select (liftA2 g pf px) empty
   where
-    g :: (a -> Bool) -> a -> Either () a
-    g f x = if f x then Right x else Left ()
-    qg :: Code ((a -> Bool) -> a -> Either () a)
-    qg = [||\f x -> if f x then Right x else Left ()||]
+    -- Not sure if I need the LET_S?
+    g =
+      LAM_S $ \f ->
+        LAM_S $ \x ->
+          LET_S x $ \x ->
+            IF_S (APP_H f x)
+                 (APP_H (makeQ Right [||Right||]) x)
+                 (makeQ (Left ()) [||Left ()||])
 
 {-|
 An alias for @(`>?>`)@.
