diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -9,6 +9,7 @@
 | `purescript` | `purescript-cst` |
 | --- | --- |
 | 0.14.2 | 0.2.0.0 |
+| 0.14.3 | 0.3.0.0 |
 
 Before v0.14.2, there was a third package, `purescript-ast`. In v0.14.2, `purescript-ast` was merged into `purescript-cst`.
 
diff --git a/purescript-cst.cabal b/purescript-cst.cabal
--- a/purescript-cst.cabal
+++ b/purescript-cst.cabal
@@ -1,6 +1,6 @@
 cabal-version:      2.4
 name:               purescript-cst
-version:            0.2.0.0
+version:            0.3.0.0
 license:            BSD-3-Clause
 license-file:       LICENSE
 copyright:
diff --git a/src/Language/PureScript/AST/Declarations.hs b/src/Language/PureScript/AST/Declarations.hs
--- a/src/Language/PureScript/AST/Declarations.hs
+++ b/src/Language/PureScript/AST/Declarations.hs
@@ -147,6 +147,9 @@
     addDefaultImport (Qualified (Just primModName) primModName)
       . addDefaultImport (Qualified Nothing primModName)
 
+data NameSource = UserNamed | CompilerNamed
+  deriving (Show, Generic, NFData, Serialise)
+
 -- |
 -- An item in a list of explicit imports or exports
 --
@@ -172,9 +175,9 @@
   --
   | ValueOpRef SourceSpan (OpName 'ValueOpName)
   -- |
-  -- A type class instance, created during typeclass desugaring (name, class name, instance types)
+  -- A type class instance, created during typeclass desugaring
   --
-  | TypeInstanceRef SourceSpan Ident
+  | TypeInstanceRef SourceSpan Ident NameSource
   -- |
   -- A module, in its entirety
   --
@@ -192,7 +195,7 @@
   (TypeRef _ name dctors) == (TypeRef _ name' dctors') = name == name' && dctors == dctors'
   (ValueRef _ name) == (ValueRef _ name') = name == name'
   (ValueOpRef _ name) == (ValueOpRef _ name') = name == name'
-  (TypeInstanceRef _ name) == (TypeInstanceRef _ name') = name == name'
+  (TypeInstanceRef _ name _) == (TypeInstanceRef _ name' _) = name == name'
   (ModuleRef _ name) == (ModuleRef _ name') = name == name'
   (ReExportRef _ mn ref) == (ReExportRef _ mn' ref') = mn == mn' && ref == ref'
   _ == _ = False
@@ -203,7 +206,7 @@
   TypeRef _ name dctors `compare` TypeRef _ name' dctors' = compare name name' <> compare dctors dctors'
   ValueRef _ name `compare` ValueRef _ name' = compare name name'
   ValueOpRef _ name `compare` ValueOpRef _ name' = compare name name'
-  TypeInstanceRef _ name `compare` TypeInstanceRef _ name' = compare name name'
+  TypeInstanceRef _ name _ `compare` TypeInstanceRef _ name' _ = compare name name'
   ModuleRef _ name `compare` ModuleRef _ name' = compare name name'
   ReExportRef _ mn ref `compare` ReExportRef _ mn' ref' = compare mn mn' <> compare ref ref'
   compare ref ref' =
@@ -232,7 +235,7 @@
 declRefSourceSpan (ValueRef ss _) = ss
 declRefSourceSpan (ValueOpRef ss _) = ss
 declRefSourceSpan (TypeClassRef ss _) = ss
-declRefSourceSpan (TypeInstanceRef ss _) = ss
+declRefSourceSpan (TypeInstanceRef ss _ _) = ss
 declRefSourceSpan (ModuleRef ss _) = ss
 declRefSourceSpan (ReExportRef ss _ _) = ss
 
@@ -242,7 +245,7 @@
 declRefName (ValueRef _ n) = IdentName n
 declRefName (ValueOpRef _ n) = ValOpName n
 declRefName (TypeClassRef _ n) = TyClassName n
-declRefName (TypeInstanceRef _ n) = IdentName n
+declRefName (TypeInstanceRef _ n _) = IdentName n
 declRefName (ModuleRef _ n) = ModName n
 declRefName (ReExportRef _ _ ref) = declRefName ref
 
@@ -473,8 +476,10 @@
   | NewtypeSig
   | TypeSynonymSig
   | ClassSig
-  deriving (Eq, Ord, Show)
+  deriving (Eq, Ord, Show, Generic)
 
+instance NFData KindSignatureFor
+
 declSourceAnn :: Declaration -> SourceAnn
 declSourceAnn (DataDeclaration sa _ _ _ _) = sa
 declSourceAnn (DataBindingGroupDeclaration ds) = declSourceAnn (NEL.head ds)
@@ -495,6 +500,9 @@
 declSourceSpan :: Declaration -> SourceSpan
 declSourceSpan = fst . declSourceAnn
 
+-- Note: Kind Declarations' names can refer to either a `TyClassName`
+-- or a `TypeName`. Use a helper function for handling `KindDeclaration`s
+-- specifically in the context in which it is needed.
 declName :: Declaration -> Maybe Name
 declName (DataDeclaration _ _ n _ _) = Just (TyName n)
 declName (TypeSynonymDeclaration _ n _ _) = Just (TyName n)
@@ -830,6 +838,7 @@
 newtype AssocList k t = AssocList { runAssocList :: [(k, t)] }
   deriving (Show, Eq, Ord, Foldable, Functor, Traversable)
 
+$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''NameSource)
 $(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''DeclarationRef)
 $(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''ImportDeclarationType)
 $(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''ExportSource)
diff --git a/src/Language/PureScript/AST/Exported.hs b/src/Language/PureScript/AST/Exported.hs
--- a/src/Language/PureScript/AST/Exported.hs
+++ b/src/Language/PureScript/AST/Exported.hs
@@ -7,6 +7,7 @@
 import Protolude (sortOn)
 
 import Control.Category ((>>>))
+import Control.Applicative ((<|>))
 
 import Data.Maybe (mapMaybe)
 import qualified Data.Map as M
@@ -30,6 +31,8 @@
 -- list, unless there is no export list, in which case they appear in the same
 -- order as they do in the source file.
 --
+-- Kind signatures declarations are also exported if their associated
+-- declaration is exported.
 exportedDeclarations :: Module -> [Declaration]
 exportedDeclarations (Module _ _ mn decls exps) = go decls
   where
@@ -126,6 +129,11 @@
 isExported :: Maybe [DeclarationRef] -> Declaration -> Bool
 isExported Nothing _ = True
 isExported _ TypeInstanceDeclaration{} = True
+isExported (Just exps) (KindDeclaration _ _ n _) = any matches exps
+  where
+  matches declRef = do
+    let refName = declRefName declRef
+    TyName n == refName || TyClassName (tyToClassName n) == refName
 isExported (Just exps) decl = any matches exps
   where
   matches declRef = declName decl == Just (declRefName declRef)
@@ -152,5 +160,14 @@
   where
   refIndices =
     M.fromList $ zip (map declRefName refs) [(0::Int)..]
-  refIndex decl =
-    declName decl >>= flip M.lookup refIndices
+  refIndex = \case
+    KindDeclaration _ _ n _ ->
+      M.lookup (TyName n) refIndices <|> M.lookup (TyClassName (tyToClassName n)) refIndices
+
+    decl -> declName decl >>= flip M.lookup refIndices
+
+-- |
+-- Workaround to the fact that a `KindDeclaration`'s name's `ProperNameType`
+-- isn't the same as the corresponding `TypeClassDeclaration`'s `ProperNameType`
+tyToClassName :: ProperName 'TypeName -> ProperName 'ClassName
+tyToClassName = coerceProperName
diff --git a/src/Language/PureScript/CST/Convert.hs b/src/Language/PureScript/CST/Convert.hs
--- a/src/Language/PureScript/CST/Convert.hs
+++ b/src/Language/PureScript/CST/Convert.hs
@@ -18,6 +18,7 @@
 import Prelude hiding (take)
 
 import Data.Bifunctor (bimap, first)
+import Data.Char (toLower)
 import Data.Foldable (foldl', toList)
 import Data.Functor (($>))
 import qualified Data.List.NonEmpty as NE
@@ -540,13 +541,17 @@
     where
       -- truncate to 25 chars to reduce verbosity
       -- of name and still keep it readable
-      -- unique identifier will be appended to this name
-      -- in desugaring proces
+      -- name will be used to create a GenIdent
+      -- in desugaring process
       genName :: Text.Text
-      genName = "$_" <> Text.take 25 (className <> typeArgs) <> "_"
+      genName = Text.take 25 (className <> typeArgs)
 
       className :: Text.Text
-      className = N.runProperName $ qualName cls
+      className
+        = foldMap (uncurry Text.cons . first toLower)
+        . Text.uncons
+        . N.runProperName
+        $ qualName cls
 
       typeArgs :: Text.Text
       typeArgs = foldMap argName args
diff --git a/src/Language/PureScript/Names.hs b/src/Language/PureScript/Names.hs
--- a/src/Language/PureScript/Names.hs
+++ b/src/Language/PureScript/Names.hs
@@ -97,6 +97,10 @@
 freshIdent' :: MonadSupply m => m Ident
 freshIdent' = GenIdent Nothing <$> fresh
 
+isPlainIdent :: Ident -> Bool
+isPlainIdent Ident{} = True
+isPlainIdent _ = False
+
 -- |
 -- Operator alias names.
 --
diff --git a/src/Language/PureScript/TypeClassDictionaries.hs b/src/Language/PureScript/TypeClassDictionaries.hs
--- a/src/Language/PureScript/TypeClassDictionaries.hs
+++ b/src/Language/PureScript/TypeClassDictionaries.hs
@@ -33,6 +33,9 @@
     , tcdInstanceTypes :: [SourceType]
     -- | Type class dependencies which must be satisfied to construct this dictionary
     , tcdDependencies :: Maybe [SourceConstraint]
+    -- | If this instance was unnamed, the type to use when describing it in
+    -- error messages
+    , tcdDescription :: Maybe SourceType
     }
     deriving (Show, Functor, Foldable, Traversable, Generic)
 
diff --git a/src/Language/PureScript/Types.hs b/src/Language/PureScript/Types.hs
--- a/src/Language/PureScript/Types.hs
+++ b/src/Language/PureScript/Types.hs
@@ -14,7 +14,7 @@
 import Data.Aeson ((.:), (.:?), (.!=), (.=))
 import qualified Data.Aeson as A
 import qualified Data.Aeson.Types as A
-import Data.Foldable (fold)
+import Data.Foldable (fold, foldl')
 import qualified Data.IntSet as IS
 import Data.List (sort, sortOn)
 import Data.Maybe (fromMaybe, isJust)
@@ -589,6 +589,20 @@
   where
   go acc (ConstrainedType _ con ty) = go (con : acc) ty
   go acc ty = (reverse acc, ty)
+
+-- | Construct the type of an instance declaration from its parts. Used in
+-- error messages describing unnamed instances.
+srcInstanceType
+  :: SourceSpan
+  -> [(Text, SourceType)]
+  -> Qualified (ProperName 'ClassName)
+  -> [SourceType]
+  -> SourceType
+srcInstanceType ss vars className tys
+  = setAnnForType (ss, [])
+  . flip (foldr $ \(tv, k) ty -> srcForAll tv (Just k) ty Nothing) vars
+  . flip (foldl' srcTypeApp) tys
+  $ srcTypeConstructor $ coerceProperName <$> className
 
 everywhereOnTypes :: (Type a -> Type a) -> Type a -> Type a
 everywhereOnTypes f = go where
