diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,6 @@
+0.12.0
+	* Type-safe quasi-quoters wrt [MR #39](https://github.com/hasufell/hpath/pull/39)
+	* Allow "." as relative dir wrt #36
 0.11.0
 	* Many API breaking changes
 	* Remove RelC and Fn, because they complicate API/break semantics (see #29)
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -4,7 +4,11 @@
 
 Support for well-typed paths in Haskell.
 
-This package is part of the HPath suite, also check out [hpath-filepath](https://hackage.haskell.org/package/hpath-filepath) and [hpath-io](https://hackage.haskell.org/package/hpath-io).
+This package is part of the HPath suite, also check out:
+
+* [hpath-directory](https://hackage.haskell.org/package/hpath-directory)
+* [hpath-filepath](https://hackage.haskell.org/package/hpath-filepath)
+* [hpath-io](https://hackage.haskell.org/package/hpath-io)
 
 ## Motivation
 
diff --git a/hpath.cabal b/hpath.cabal
--- a/hpath.cabal
+++ b/hpath.cabal
@@ -1,5 +1,5 @@
 name:                hpath
-version:             0.11.0
+version:             0.12.0
 synopsis:            Support for well-typed paths
 description:         Support for well-typed paths, utilizing ByteString under the hood.
 license:             BSD3
diff --git a/src/HPath.hs b/src/HPath.hs
--- a/src/HPath.hs
+++ b/src/HPath.hs
@@ -18,6 +18,7 @@
 #endif
 {-# LANGUAGE QuasiQuotes #-}
 {-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE ScopedTypeVariables #-}
 
 module HPath
   (
@@ -36,6 +37,7 @@
   ,parseRel
   ,parseAny
   ,rootPath
+  ,pwdPath
   -- * Path Conversion
   ,fromAbs
   ,fromRel
@@ -52,6 +54,7 @@
   -- * Path Examination
   ,isParentOf
   ,isRootPath
+  ,isPwdPath
   -- * Path IO helpers
   ,withAbsPath
   ,withRelPath
@@ -61,6 +64,7 @@
   )
   where
 
+import           Control.Applicative ((<|>))
 import           Control.Exception (Exception)
 import           Control.Monad.Catch (MonadThrow(..))
 #if MIN_VERSION_bytestring(0,10,8)
@@ -76,7 +80,8 @@
 import           Data.Word8
 import           HPath.Internal
 import           Language.Haskell.TH
-import           Language.Haskell.TH.Syntax (Exp(..), Lift(..), lift)
+import           Language.Haskell.TH.Syntax (Lift(..), lift)
+import qualified Language.Haskell.TH.Syntax as TH
 import           Language.Haskell.TH.Quote (QuasiQuoter(..))
 import           Prelude hiding (abs, any)
 import           System.Posix.FilePath hiding ((</>))
@@ -150,8 +155,8 @@
 -- | Get a location for a relative path. Produces a normalised
 -- path.
 --
--- Note that @filepath@ may contain any number of @./@ but may not consist
--- solely of @./@.  It also may not contain a single @..@ anywhere.
+-- Note that @filepath@ may contain any number of @./@.
+-- It also may not contain a single @..@ anywhere.
 --
 -- Throws: 'PathParseException'
 --
@@ -170,14 +175,17 @@
 -- >>> parseRel "abc/../foo" :: Maybe (Path Rel)
 -- Nothing
 -- >>> parseRel "."          :: Maybe (Path Rel)
--- Nothing
+-- Just "."
+-- >>> parseRel "././././."  :: Maybe (Path Rel)
+-- Just "."
+-- >>> parseRel "./..."      :: Maybe (Path Rel)
+-- Just "..."
 -- >>> parseRel ".."         :: Maybe (Path Rel)
 -- Nothing
 parseRel :: MonadThrow m
          => ByteString -> m (Path Rel)
 parseRel filepath =
   if not (isAbsolute filepath) &&
-     filepath /= BS.singleton _period &&
      filepath /= BS.pack [_period, _period] &&
      not (hasParentDir filepath) &&
      isValid filepath
@@ -186,11 +194,8 @@
 
 
 
--- | Parses a path, whether it's relative or absolute. Will lose
--- information on whether it's relative or absolute. If you need to know,
--- reparse it.
+-- | Parses a path, whether it's relative or absolute.
 --
--- Filenames must not contain slashes.
 -- Excludes '.' and '..'.
 --
 -- Throws: 'PathParseException'
@@ -210,7 +215,7 @@
 -- >>> parseAny "abc/../foo" :: Maybe (Either (Path Abs) (Path Rel))
 -- Nothing
 -- >>> parseAny "."          :: Maybe (Either (Path Abs) (Path Rel))
--- Nothing
+-- Just (Right ".")
 -- >>> parseAny ".."         :: Maybe (Either (Path Abs) (Path Rel))
 -- Nothing
 parseAny :: MonadThrow m => ByteString -> m (Either (Path Abs) (Path Rel))
@@ -224,7 +229,10 @@
 rootPath :: Path Abs
 rootPath = (MkPath (BS.singleton _slash))
 
+pwdPath :: Path Rel
+pwdPath = (MkPath (BS.singleton _period))
 
+
 --------------------------------------------------------------------------------
 -- Path Conversion
 
@@ -262,14 +270,15 @@
 -- "/path/to/file"
 -- >>> (MkPath "/")        </> (MkPath "file/lal" :: Path Rel)
 -- "/file/lal"
--- >>> (MkPath "/")        </> (MkPath "file"    :: Path Rel)
+-- >>> (MkPath "/")        </> (MkPath "file/"    :: Path Rel)
 -- "/file"
+-- >>> (MkPath "/")        </> (MkPath "."        :: Path Rel)
+-- "/"
+-- >>> (MkPath ".")        </> (MkPath "."        :: Path Rel)
+-- "."
 (</>) :: Path b -> Path Rel -> Path b
-(</>) (MkPath a) (MkPath b) = MkPath (a' `BS.append` b)
-  where
-    a' = if hasTrailingPathSeparator a
-            then a
-            else addTrailingPathSeparator a
+(</>) (MkPath a) (MkPath b) =
+  MkPath (dropTrailingPathSeparator $ normalise (addTrailingPathSeparator a `BS.append` b))
 
 
 -- | Strip directory from path, making it relative to that directory.
@@ -282,18 +291,20 @@
 -- >>> (MkPath "lal/lad")      `stripDir` (MkPath "lal/lad/fad")  :: Maybe (Path Rel)
 -- Just "fad"
 -- >>> (MkPath "/")            `stripDir` (MkPath "/")            :: Maybe (Path Rel)
--- Nothing
+-- Just "."
 -- >>> (MkPath "/lal/lad/fad") `stripDir` (MkPath "/lal/lad")     :: Maybe (Path Rel)
 -- Nothing
--- >>> (MkPath "fad")          `stripDir` (MkPath "fad")          :: Maybe (Path Rel)
+-- >>> (MkPath "/abs")         `stripDir` (MkPath "/lal/lad")     :: Maybe (Path Rel)
 -- Nothing
+-- >>> (MkPath "fad")          `stripDir` (MkPath "fad")          :: Maybe (Path Rel)
+-- Just "."
 stripDir :: MonadThrow m
          => Path b -> Path b -> m (Path Rel)
 stripDir (MkPath p) (MkPath l) =
-  case stripPrefix p' l of
+  case stripPrefix p' l <|> stripPrefix p l of
     Nothing -> throwM (Couldn'tStripPrefixTPS p' l)
     Just ok -> if BS.null ok
-                 then throwM (Couldn'tStripPrefixTPS p' l)
+                 then return (MkPath $ BS.singleton _period)
                  else return (MkPath ok)
   where
     p' = addTrailingPathSeparator p
@@ -359,6 +370,8 @@
 -- Just "dod"
 -- >>> basename (MkPath "dod")          :: Maybe (Path Rel)
 -- Just "dod"
+-- >>> basename (MkPath ".")            :: Maybe (Path Rel)
+-- Just "."
 -- >>> basename (MkPath "/")            :: Maybe (Path Rel)
 -- Nothing
 basename :: MonadThrow m => Path b -> m (Path Rel)
@@ -387,7 +400,11 @@
 -- >>> (MkPath "fad")          `isParentOf` (MkPath "fad")
 -- False
 isParentOf :: Path b -> Path b -> Bool
-isParentOf p l = isJust (stripDir p l :: Maybe (Path Rel))
+isParentOf p l = case stripDir p l :: Maybe (Path Rel) of
+  Nothing -> False
+  Just ok
+    | isPwdPath ok -> False
+    | otherwise -> True
 
 
 -- | Check whether the given Path is the root "/" path.
@@ -399,7 +416,16 @@
 isRootPath :: Path Abs -> Bool
 isRootPath = (== rootPath)
 
+-- | Check whether the given Path is the pwd "." path.
+--
+-- >>> isPwdPath (MkPath "/lal/lad")
+-- False
+-- >>> isPwdPath (MkPath ".")
+-- True
+isPwdPath :: Path Rel -> Bool
+isPwdPath = (== pwdPath)
 
+
 --------------------------------------------------------------------------------
 -- Path IO helpers
 
@@ -426,8 +452,14 @@
 ------------------------
 -- QuasiQuoters
 
-instance Lift (Path a) where
-  lift (MkPath bs) = AppE <$> [| MkPath . BS.pack |] <*> lift (BS.unpack bs)
+instance Typeable a => Lift (Path a) where
+  lift (MkPath bs) = [| MkPath (BS.pack $(lift $ BS.unpack bs)) :: Path $(pure a) |]
+    where
+      a = TH.ConT $ TH.Name occ flav
+        where
+        tc   = typeRepTyCon (typeRep (Proxy :: Proxy a))
+        occ  = TH.OccName (tyConName tc)
+        flav = TH.NameG TH.TcClsName (TH.PkgName (tyConPackage tc)) (TH.ModName (tyConModule tc))
 
 
 qq :: (ByteString -> Q Exp) -> QuasiQuoter
