diff --git a/benchmarks/BigTable/Hamlet.hs b/benchmarks/BigTable/Hamlet.hs
new file mode 100644
--- /dev/null
+++ b/benchmarks/BigTable/Hamlet.hs
@@ -0,0 +1,53 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE QuasiQuotes       #-}
+module BigTable.Hamlet where
+import           Criterion                     (Benchmark, bench, nf)
+import           Data.Text.Lazy                (Text)
+import           Text.Blaze.Html.Renderer.Text (renderHtml)
+import           Text.Hamlet
+import           Weigh
+
+bigTable :: [[Int]] -> Text
+bigTable rows = renderHtml $
+  [hamlet|
+  <h1>i am a real big old table
+  <p>i am good at lots of static data
+  <p>i am glab at lots of static data
+  <p>i am glob at lots of static data
+  <p>i am glib at lots of static data
+  <p>i am glub at lots of static data
+  <p>i am glom at lots of static data
+  <p>i am glof at lots of static data
+  <p>i am gref at lots of static data
+  <p>i am greg at lots of static data
+  <table>
+    <thead>
+      <tr>
+        $forall i <- header
+          <th>#{i}
+    <tbody>
+      $forall row <- rows
+        <tr>
+          $forall col <- row
+            <td>
+              <p>hi!
+              #{col}
+              <p>hello!
+  <p>i am good at lots of static data
+  <p>i am glab at lots of static data
+  <p>i am glob at lots of static data
+  <p>i am glib at lots of static data
+  <p>i am glub at lots of static data
+  <p>i am glom at lots of static data
+  <p>i am glof at lots of static data
+  <p>i am gref at lots of static data
+  <p>i am greg at lots of static data|]
+  ()
+  where
+    header = [1..10 :: Int]
+
+benchmark :: [[Int]] -> Benchmark
+benchmark rows = bench "hamlet" (bigTable `nf` rows)
+
+weight :: [[Int]] -> Weigh ()
+weight i = func (show (length i) ++ "/hamlet") bigTable i
diff --git a/benchmarks/BigTable/Nice.hs b/benchmarks/BigTable/Nice.hs
--- a/benchmarks/BigTable/Nice.hs
+++ b/benchmarks/BigTable/Nice.hs
@@ -24,9 +24,9 @@
   p_ "i am greg at lots of static data\n"
   table_ $ do
     thead_ . tr_ . mapM_ (th_ . builder . decimal) $ [1..10 :: Int]
-    tbody_ . stream . tr_ . stream $ do
+    tbody_ . stream . tr_ . stream . td_ $ do
       p_ "hi!\n"
-      td_ (dynamic decimal)
+      dynamic decimal
       p_ "hello!\n"
   p_ "i am good at lots of static data\n"
   p_ "i am glab at lots of static data\n"
diff --git a/benchmarks/BigTable/TypeOfHtml.hs b/benchmarks/BigTable/TypeOfHtml.hs
new file mode 100644
--- /dev/null
+++ b/benchmarks/BigTable/TypeOfHtml.hs
@@ -0,0 +1,47 @@
+{-# LANGUAGE OverloadedStrings #-}
+module BigTable.TypeOfHtml where
+import           Criterion.Main (Benchmark, bench, nf)
+import           Data.Text.Lazy (Text)
+import           Html
+import           Weigh          (Weigh, func)
+
+-- | Render the argument matrix as an HTML table.
+--
+bigTable :: [[Int]]  -- ^ Matrix.
+         -> Text     -- ^ Result.
+bigTable rows = renderText $
+  h1_ ("i am a real big old table\n" :: Text)
+  # p_ ("i am good at lots of static data\n" :: Text)
+  # p_ ("i am glab at lots of static data\n" :: Text)
+  # p_ ("i am glob at lots of static data\n" :: Text)
+  # p_ ("i am glib at lots of static data\n" :: Text)
+  # p_ ("i am glub at lots of static data\n" :: Text)
+  # p_ ("i am glom at lots of static data\n" :: Text)
+  # p_ ("i am glof at lots of static data\n" :: Text)
+  # p_ ("i am gref at lots of static data\n" :: Text)
+  # p_ ("i am greg at lots of static data\n" :: Text)
+  # table_ (
+    thead_ (tr_ (map (th_ . show) [1..10 :: Int]))
+    # tbody_ (map row rows))
+  # p_ ("i am good at lots of static data\n" :: Text)
+  # p_ ("i am glab at lots of static data\n" :: Text)
+  # p_ ("i am glob at lots of static data\n" :: Text)
+  # p_ ("i am glib at lots of static data\n" :: Text)
+  # p_ ("i am glub at lots of static data\n" :: Text)
+  # p_ ("i am glom at lots of static data\n" :: Text)
+  # p_ ("i am glof at lots of static data\n" :: Text)
+  # p_ ("i am gref at lots of static data\n" :: Text)
+  # p_ ("i am greg at lots of static data\n" :: Text)
+  where
+    row r = tr_ (map
+                 (\t -> td_ $
+                   p_ ("hi!\n" :: Text)
+                   # show t
+                   # p_ ("hello!\n" :: Text))
+                 r)
+
+benchmark :: [[Int]] -> Benchmark
+benchmark rows = bench "type-of-html" (bigTable `nf` rows)
+
+weight :: [[Int]] -> Weigh ()
+weight i = func (show (length i) ++ "/type-of-html") bigTable i
diff --git a/benchmarks/Perf.hs b/benchmarks/Perf.hs
--- a/benchmarks/Perf.hs
+++ b/benchmarks/Perf.hs
@@ -1,7 +1,9 @@
 {-# LANGUAGE BangPatterns #-}
 import qualified BigTable.Blaze      as Blaze
+import qualified BigTable.Hamlet     as Hamlet
 import qualified BigTable.Lucid      as Lucid
 import qualified BigTable.Nice       as Nice
+import qualified BigTable.TypeOfHtml as TypeOfHtml
 import qualified Criterion.Main      as Perf
 import qualified Data.Text.Lazy.IO   as T
 
@@ -11,7 +13,6 @@
 
 main :: IO ()
 main = do
-{-
   -- Sanity checks
   let
     check l f g =
@@ -29,14 +30,17 @@
 
   check "nice = blaze" Nice.bigTable Blaze.bigTable
   check "nice = lucid" Nice.bigTable Lucid.bigTable
-  check "lucid = blaze" Lucid.bigTable Blaze.bigTable
--}
+  -- check "nice = hamlet" Nice.bigTable Hamlet.bigTable
+  -- hamlet can't produce exactly same html
+  check "nice = type-of-html" Nice.bigTable TypeOfHtml.bigTable
 
   Perf.defaultMain
     [ Perf.bgroup (show i)
       [ Blaze.benchmark (rows i)
       , Nice.benchmark (rows i)
       , Lucid.benchmark (rows i)
+      , Hamlet.benchmark (rows i)
+      , TypeOfHtml.benchmark (rows i)
       ]
     | i <- [10, 100, 1000]
     ]
diff --git a/nice-html.cabal b/nice-html.cabal
--- a/nice-html.cabal
+++ b/nice-html.cabal
@@ -1,5 +1,5 @@
 name:           nice-html
-version:        0.4.0
+version:        0.4.1
 category:       Web
 description: A fast and nice HTML templating library with distinct compilation/rendering phases.
 synopsis: A fast and nice HTML templating library with distinct compilation/rendering phases.
@@ -56,7 +56,7 @@
       benchmarks
   ghc-options: -Wall -O2
   build-depends:
-      base == 4.9.*
+      base >= 4.9
     , criterion
     , blaze-markup
     , blaze-html
@@ -80,7 +80,7 @@
       benchmarks
   ghc-options: -Wall -O2
   build-depends:
-      base == 4.9.*
+      base >= 4.9
     , criterion
     , blaze-markup
     , blaze-html
@@ -102,7 +102,7 @@
       benchmarks
   ghc-options: -Wall -O2
   build-depends:
-      base == 4.9.*
+      base >= 4.9
     , criterion
     , blaze-markup
     , blaze-html
@@ -113,8 +113,12 @@
     , weigh
     , pretty-show
     , transformers
+    , shakespeare
+    , type-of-html
   other-modules:
       BigTable.Blaze
       BigTable.Lucid
       BigTable.Nice
+      BigTable.Hamlet
+      BigTable.TypeOfHtml
   default-language: Haskell2010
diff --git a/src/Text/Html/Nice/FreeMonad.hs b/src/Text/Html/Nice/FreeMonad.hs
--- a/src/Text/Html/Nice/FreeMonad.hs
+++ b/src/Text/Html/Nice/FreeMonad.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE BangPatterns               #-}
+{-# LANGUAGE CPP                        #-}
 {-# LANGUAGE ConstraintKinds            #-}
 {-# LANGUAGE DataKinds                  #-}
 {-# LANGUAGE FlexibleInstances          #-}
@@ -9,6 +10,7 @@
 {-# LANGUAGE OverloadedLists            #-}
 {-# LANGUAGE OverloadedStrings          #-}
 {-# LANGUAGE RankNTypes                 #-}
+{-# LANGUAGE ScopedTypeVariables        #-}
 {-# LANGUAGE TypeFamilies               #-}
 {-# LANGUAGE TypeFamilyDependencies     #-}
 {-# LANGUAGE TypeOperators              #-}
@@ -96,6 +98,9 @@
 import           Data.Foldable                    as F
 import qualified Data.Functor.Foldable            as F
 import           Data.Functor.Identity
+#if __GLASGOW_HASKELL__ >= 802
+import           Data.Proxy                       (Proxy (..))
+#endif
 import           Data.String                      (IsString (..))
 import           Data.Text                        (Text)
 import qualified Data.Text.Lazy                   as TL
@@ -106,7 +111,11 @@
 import           Data.Void
 import           GHC.Exts                         (IsList (..))
 import           GHC.OverloadedLabels             (IsLabel (..))
+#if __GLASGOW_HASKELL__ >= 802
+import           GHC.TypeLits                     (KnownSymbol, symbolVal)
+#else
 import           GHC.TypeLits                     (KnownSymbol, symbolVal')
+#endif
 import           Text.Html.Nice.Internal
 
 -- | 'Markup' is a free monad based on the base functor to 'Markup\'F'
@@ -152,12 +161,20 @@
   toList _ = error "haha, fooled you, Markup has no toList"
 
 instance (a ~ (), KnownSymbol s) => IsLabel s (Markup n a) where
+#if __GLASGOW_HASKELL__ >= 802
+  fromLabel = node (fromString (symbolVal (Proxy :: Proxy s))) []
+#else
   fromLabel p = node (fromString (symbolVal' p)) []
+#endif
 
 newtype MakeNode n a = N ([Attr n] -> Markup n a)
 
 instance (a ~ (), KnownSymbol s) => IsLabel s (MakeNode n a) where
+#if __GLASGOW_HASKELL__ >= 802
+  fromLabel = N (node (fromString (symbolVal (Proxy :: Proxy s))))
+#else
   fromLabel p = N (node (fromString (symbolVal' p)))
+#endif
 
 instance Bifunctor Markup where
   first f = Markup . hoistF (first f) . unMarkup
