diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -53,6 +53,7 @@
 | [@kika](https://github.com/kika) | Kirill Pertsev | MIT license |
 | [@kRITZCREEK](https://github.com/kRITZCREEK) | Christoph Hegemann | MIT license |
 | [@L8D](https://github.com/L8D) | Tenor Biel | [MIT license](http://opensource.org/licenses/MIT) |
+| [@legrostdg](https://github.com/legrostdg) | Félix Sipma | [MIT license](http://opensource.org/licenses/MIT) |
 | [@LiamGoodacre](https://github.com/LiamGoodacre) | Liam Goodacre | [MIT license](http://opensource.org/licenses/MIT) |
 | [@lukerandall](https://github.com/lukerandall) | Luke Randall | [MIT license](http://opensource.org/licenses/MIT) |
 | [@matthewleon](https://github.com/matthewleon) | Matthew Leon | [MIT license](http://opensource.org/licenses/MIT) |
diff --git a/examples/passing/2795.purs b/examples/passing/2795.purs
new file mode 100644
--- /dev/null
+++ b/examples/passing/2795.purs
@@ -0,0 +1,14 @@
+module Main where
+
+import Prelude
+import Control.Monad.Eff.Console (log)
+
+data X = X Int | Y
+
+x :: X -> Int
+x = case _ of
+      Y -> 0
+      X n | 1 <- n -> 1
+          | otherwise -> 2
+
+main = log "Done"
diff --git a/examples/passing/PolyLabels.js b/examples/passing/PolyLabels.js
new file mode 100644
--- /dev/null
+++ b/examples/passing/PolyLabels.js
@@ -0,0 +1,17 @@
+"use strict";
+
+exports.unsafeGet = function (s) {
+  return function (o) {
+    return o[s];
+  };
+};
+
+exports.unsafeSet = function(s) {
+  return function(a) {
+    return function (o) {
+      var o1 = {};
+      o1[s] = a;
+      return Object.assign({}, o, o1);
+    };
+  };
+};
diff --git a/examples/passing/PolyLabels.purs b/examples/passing/PolyLabels.purs
new file mode 100644
--- /dev/null
+++ b/examples/passing/PolyLabels.purs
@@ -0,0 +1,65 @@
+module Main where
+
+import Prelude
+import Control.Monad.Eff
+import Control.Monad.Eff.Console
+import Data.Symbol (class IsSymbol, SProxy(..), reflectSymbol)
+
+foreign import unsafeGet
+  :: forall r a
+   . String
+  -> Record r
+  -> a
+
+foreign import unsafeSet
+  :: forall r1 r2 a
+   . String
+  -> a
+  -> Record r1
+  -> Record r2
+
+get
+  :: forall r r' l a
+   . IsSymbol l
+  => RowCons l a r' r
+  => SProxy l
+  -> Record r
+  -> a
+get l = unsafeGet (reflectSymbol l)
+
+set
+  :: forall r1 r2 r l a b
+   . IsSymbol l
+  => RowCons l a r r1
+  => RowCons l b r r2
+  => SProxy l
+  -> b
+  -> Record r1
+  -> Record r2
+set l = unsafeSet (reflectSymbol l)
+
+lens 
+  :: forall l f r1 r2 r a b
+   . IsSymbol l
+  => RowCons l a r r1
+  => RowCons l b r r2
+  => Functor f
+  => SProxy l
+  -> (a -> f b)
+  -> Record r1
+  -> f (Record r2)
+lens l f r = flip (set l) r <$> f (get l r)
+
+getFoo :: forall a r. { foo :: a | r } -> a
+getFoo = get (SProxy :: SProxy "foo")
+
+setFoo :: forall a b r. b -> { foo :: a | r } -> { foo :: b | r }
+setFoo = set (SProxy :: SProxy "foo")
+
+fooLens :: forall f a b r. Functor f => (a -> f b) -> { foo :: a | r } -> f { foo :: b | r } 
+fooLens = lens (SProxy :: SProxy "foo")
+
+main :: Eff (console :: CONSOLE) Unit
+main = do
+  _ <- fooLens logShow { foo: 1 }
+  log (getFoo (setFoo "Done" { foo: 1 }))
diff --git a/examples/psci/BasicEval.purs b/examples/psci/BasicEval.purs
new file mode 100644
--- /dev/null
+++ b/examples/psci/BasicEval.purs
@@ -0,0 +1,10 @@
+import Prelude
+import Data.Array
+
+-- @shouldEvaluateTo 3628800
+let fac n = foldl mul 1 (1..n) in fac 10
+
+fac n = foldl mul 1 (1..n)
+
+-- @shouldEvaluateTo 3628800
+fac 10
diff --git a/examples/psci/Multiline.purs b/examples/psci/Multiline.purs
new file mode 100644
--- /dev/null
+++ b/examples/psci/Multiline.purs
@@ -0,0 +1,10 @@
+import Prelude
+import Data.Array
+
+-- @paste
+fac :: Int -> Int
+fac n = foldl mul 1 (1..n)
+-- @paste
+
+-- @shouldEvaluateTo 3628800
+fac 10
diff --git a/purescript.cabal b/purescript.cabal
--- a/purescript.cabal
+++ b/purescript.cabal
@@ -1,466 +1,1026 @@
-name: purescript
-version: 0.11.1
-cabal-version: >=1.8
-build-type: Simple
-license: BSD3
-license-file: LICENSE
-copyright: (c) 2013-16 Phil Freeman, (c) 2014-16 Gary Burgess
-maintainer: Phil Freeman <paf31@cantab.net>
-stability: experimental
-synopsis: PureScript Programming Language Compiler
-description: A small strongly, statically typed programming language with expressive types, inspired by Haskell and compiling to JavaScript.
-category: Language
-Homepage: http://www.purescript.org/
-author: Phil Freeman <paf31@cantab.net>,
-        Gary Burgess <gary.burgess@gmail.com>,
-        Hardy Jones <jones3.hardy@gmail.com>,
-        Harry Garrood <harry@garrood.me>,
-        Christoph Hegemann <christoph.hegemann1337@gmail.com>
-
-tested-with: GHC==7.10.3
-
-extra-source-files: examples/passing/*.purs
-                  , examples/passing/*.js
-                  , examples/passing/2018/*.purs
-                  , examples/passing/2138/*.purs
-                  , examples/passing/2609/*.purs
-                  , examples/passing/ClassRefSyntax/*.purs
-                  , examples/passing/DctorOperatorAlias/*.purs
-                  , examples/passing/ExplicitImportReExport/*.purs
-                  , examples/passing/ExportExplicit/*.purs
-                  , examples/passing/ExportExplicit2/*.purs
-                  , examples/passing/ForeignKind/*.purs
-                  , examples/passing/Import/*.purs
-                  , examples/passing/ImportExplicit/*.purs
-                  , examples/passing/ImportQualified/*.purs
-                  , examples/passing/Module/*.purs
-                  , examples/passing/ModuleDeps/*.purs
-                  , examples/passing/ModuleExport/*.purs
-                  , examples/passing/ModuleExportDupes/*.purs
-                  , examples/passing/ModuleExportExcluded/*.purs
-                  , examples/passing/ModuleExportQualified/*.purs
-                  , examples/passing/ModuleExportSelf/*.purs
-                  , examples/passing/NonConflictingExports/*.purs
-                  , examples/passing/NonOrphanInstanceMulti/*.purs
-                  , examples/passing/NonOrphanInstanceFunDepExtra/*.purs
-                  , examples/passing/OperatorAliasElsewhere/*.purs
-                  , examples/passing/Operators/*.purs
-                  , examples/passing/PendingConflictingImports/*.purs
-                  , examples/passing/PendingConflictingImports2/*.purs
-                  , examples/passing/QualifiedNames/*.purs
-                  , examples/passing/RedefinedFixity/*.purs
-                  , examples/passing/ReExportQualified/*.purs
-                  , examples/passing/ResolvableScopeConflict/*.purs
-                  , examples/passing/ResolvableScopeConflict2/*.purs
-                  , examples/passing/ResolvableScopeConflict3/*.purs
-                  , examples/passing/ShadowedModuleName/*.purs
-                  , examples/passing/SolvingIsSymbol/*.purs
-                  , examples/passing/StringEdgeCases/*.purs
-                  , examples/passing/TransitiveImport/*.purs
-                  , examples/passing/TypeOperators/*.purs
-                  , examples/passing/TypeWithoutParens/*.purs
-                  , examples/failing/*.purs
-                  , examples/failing/1733/*.purs
-                  , examples/failing/2378/*.purs
-                  , examples/failing/2379/*.purs
-                  , examples/failing/ConflictingExports/*.purs
-                  , examples/failing/ConflictingImports/*.purs
-                  , examples/failing/ConflictingImports2/*.purs
-                  , examples/failing/ConflictingQualifiedImports/*.purs
-                  , examples/failing/ConflictingQualifiedImports2/*.purs
-                  , examples/failing/DiffKindsSameName/*.purs
-                  , examples/failing/DuplicateModule/*.purs
-                  , examples/failing/ExportConflictClass/*.purs
-                  , examples/failing/ExportConflictCtor/*.purs
-                  , examples/failing/ExportConflictType/*.purs
-                  , examples/failing/ExportConflictTypeOp/*.purs
-                  , examples/failing/ExportConflictValue/*.purs
-                  , examples/failing/ExportConflictValueOp/*.purs
-                  , examples/failing/ExportExplicit1/*.purs
-                  , examples/failing/ExportExplicit3/*.purs
-                  , examples/failing/ImportExplicit/*.purs
-                  , examples/failing/ImportExplicit2/*.purs
-                  , examples/failing/ImportHidingModule/*.purs
-                  , examples/failing/ImportModule/*.purs
-                  , examples/failing/InstanceExport/*.purs
-                  , examples/failing/OrphanInstance/*.purs
-                  , examples/failing/OrphanInstanceFunDepCycle/*.purs
-                  , examples/failing/OrphanInstanceWithDetermined/*.purs
-                  , examples/failing/OrphanInstanceNullary/*.purs
-                  , examples/warning/*.purs
-                  , examples/warning/*.js
-                  , examples/warning/UnusedExplicitImportTypeOp/*.purs
-                  , examples/docs/bower_components/purescript-prelude/src/*.purs
-                  , examples/docs/bower.json
-                  , examples/docs/src/*.purs
-                  , examples/docs/resolutions.json
-                  , app/static/index.html
-                  , app/static/index.js
-                  , app/static/*.css
-                  , tests/support/package.json
-                  , tests/support/bower.json
-                  , tests/support/setup-win.cmd
-                  , tests/support/psci/*.purs
-                  , tests/support/pscide/src/*.purs
-                  , tests/support/pscide/src/*.js
-                  , tests/support/pscide/src/*.fail
-                  , tests/support/prelude-resolutions.json
-                  , stack.yaml
-                  , README.md
-                  , INSTALL.md
-                  , CONTRIBUTORS.md
-                  , CONTRIBUTING.md
-
-source-repository head
-    type: git
-    location: https://github.com/purescript/purescript.git
-
-flag release
-  description: Mark this build as a release build: prevents inclusion of extra
-               info e.g. commit SHA in --version output)
-  default: False
-
-library
-    build-depends: base >=4.8 && <5,
-                   aeson >= 0.8 && < 1.1,
-                   aeson-better-errors >= 0.8,
-                   ansi-terminal >= 0.6.2 && < 0.7,
-                   base-compat >=0.6.0,
-                   blaze-html >= 0.8.1 && < 0.9,
-                   bower-json >= 1.0.0.1 && < 1.1,
-                   boxes >= 0.1.4 && < 0.2.0,
-                   bytestring -any,
-                   cheapskate >= 0.1 && < 0.2,
-                   containers -any,
-                   clock -any,
-                   data-ordlist >= 0.4.7.0,
-                   deepseq -any,
-                   directory >= 1.2,
-                   dlist -any,
-                   edit-distance -any,
-                   filepath -any,
-                   fsnotify >= 0.2.1,
-                   Glob >= 0.7 && < 0.8,
-                   haskeline >= 0.7.0.0,
-                   http-client >= 0.4.30 && < 0.6.0,
-                   http-types -any,
-                   language-javascript >= 0.6.0.9 && < 0.7,
-                   lens == 4.*,
-                   lifted-base >= 0.2.3 && < 0.2.4,
-                   monad-control >= 1.0.0.0 && < 1.1,
-                   monad-logger >= 0.3 && < 0.4,
-                   mtl >= 2.1.0 && < 2.3.0,
-                   parallel >= 3.2 && < 3.3,
-                   parsec >=3.1.10,
-                   pattern-arrows >= 0.0.2 && < 0.1,
-                   pipes >= 4.0.0 && < 4.4.0,
-                   pipes-http -any,
-                   process >= 1.2.0 && < 1.5,
-                   protolude >= 0.1.6,
-                   regex-tdfa -any,
-                   safe >= 0.3.9 && < 0.4,
-                   scientific >= 0.3.4.9 && < 0.4,
-                   semigroups >= 0.16.2 && < 0.19,
-                   sourcemap >= 0.1.6,
-                   spdx == 0.2.*,
-                   split -any,
-                   stm >= 0.2.4.0,
-                   syb -any,
-                   text -any,
-                   time -any,
-                   transformers >= 0.3.0 && < 0.6,
-                   transformers-base >= 0.4.0 && < 0.5,
-                   transformers-compat >= 0.3.0,
-                   unordered-containers -any,
-                   utf8-string >= 1 && < 2,
-                   vector -any
-
-    exposed-modules: Language.PureScript
-                     Language.PureScript.AST
-                     Language.PureScript.AST.Binders
-                     Language.PureScript.AST.Declarations
-                     Language.PureScript.AST.Operators
-                     Language.PureScript.AST.Literals
-                     Language.PureScript.AST.SourcePos
-                     Language.PureScript.AST.Traversals
-                     Language.PureScript.AST.Exported
-                     Language.PureScript.Bundle
-                     Language.PureScript.Crash
-                     Language.PureScript.Externs
-                     Language.PureScript.CodeGen
-                     Language.PureScript.CodeGen.JS
-                     Language.PureScript.CodeGen.JS.Common
-                     Language.PureScript.CodeGen.JS.Printer
-                     Language.PureScript.Constants
-                     Language.PureScript.CoreFn
-                     Language.PureScript.CoreFn.Ann
-                     Language.PureScript.CoreFn.Binders
-                     Language.PureScript.CoreFn.Desugar
-                     Language.PureScript.CoreFn.Expr
-                     Language.PureScript.CoreFn.Meta
-                     Language.PureScript.CoreFn.Module
-                     Language.PureScript.CoreFn.Traversals
-                     Language.PureScript.CoreFn.ToJSON
-                     Language.PureScript.CoreImp
-                     Language.PureScript.CoreImp.AST
-                     Language.PureScript.CoreImp.Optimizer
-                     Language.PureScript.CoreImp.Optimizer.Blocks
-                     Language.PureScript.CoreImp.Optimizer.Common
-                     Language.PureScript.CoreImp.Optimizer.Inliner
-                     Language.PureScript.CoreImp.Optimizer.MagicDo
-                     Language.PureScript.CoreImp.Optimizer.TCO
-                     Language.PureScript.CoreImp.Optimizer.Unused
-                     Language.PureScript.Comments
-                     Language.PureScript.Environment
-                     Language.PureScript.Errors
-                     Language.PureScript.Errors.JSON
-                     Language.PureScript.Kinds
-                     Language.PureScript.Label
-                     Language.PureScript.Linter
-                     Language.PureScript.Linter.Exhaustive
-                     Language.PureScript.Linter.Imports
-                     Language.PureScript.Make
-                     Language.PureScript.ModuleDependencies
-                     Language.PureScript.Names
-                     Language.PureScript.Options
-                     Language.PureScript.Parser
-                     Language.PureScript.Parser.Lexer
-                     Language.PureScript.Parser.Common
-                     Language.PureScript.Parser.Declarations
-                     Language.PureScript.Parser.Kinds
-                     Language.PureScript.Parser.State
-                     Language.PureScript.Parser.Types
-                     Language.PureScript.Pretty
-                     Language.PureScript.Pretty.Common
-                     Language.PureScript.Pretty.Kinds
-                     Language.PureScript.Pretty.Types
-                     Language.PureScript.Pretty.Values
-                     Language.PureScript.PSString
-                     Language.PureScript.Renamer
-                     Language.PureScript.Sugar
-                     Language.PureScript.Sugar.BindingGroups
-                     Language.PureScript.Sugar.CaseDeclarations
-                     Language.PureScript.Sugar.DoNotation
-                     Language.PureScript.Sugar.LetPattern
-                     Language.PureScript.Sugar.Names
-                     Language.PureScript.Sugar.Names.Common
-                     Language.PureScript.Sugar.Names.Env
-                     Language.PureScript.Sugar.Names.Exports
-                     Language.PureScript.Sugar.Names.Imports
-                     Language.PureScript.Sugar.ObjectWildcards
-                     Language.PureScript.Sugar.Operators
-                     Language.PureScript.Sugar.Operators.Common
-                     Language.PureScript.Sugar.Operators.Expr
-                     Language.PureScript.Sugar.Operators.Binders
-                     Language.PureScript.Sugar.Operators.Types
-                     Language.PureScript.Sugar.TypeClasses
-                     Language.PureScript.Sugar.TypeClasses.Deriving
-                     Language.PureScript.Sugar.TypeDeclarations
-                     Language.PureScript.Traversals
-                     Language.PureScript.TypeChecker
-                     Language.PureScript.TypeChecker.Entailment
-                     Language.PureScript.TypeChecker.Kinds
-                     Language.PureScript.TypeChecker.Monad
-                     Language.PureScript.TypeChecker.Skolems
-                     Language.PureScript.TypeChecker.Subsumption
-                     Language.PureScript.TypeChecker.Synonyms
-                     Language.PureScript.TypeChecker.Types
-                     Language.PureScript.TypeChecker.TypeSearch
-                     Language.PureScript.TypeChecker.Unify
-                     Language.PureScript.TypeClassDictionaries
-                     Language.PureScript.Types
-
-                     Language.PureScript.Docs
-                     Language.PureScript.Docs.Convert
-                     Language.PureScript.Docs.Convert.Single
-                     Language.PureScript.Docs.Convert.ReExports
-                     Language.PureScript.Docs.Prim
-                     Language.PureScript.Docs.Render
-                     Language.PureScript.Docs.Types
-                     Language.PureScript.Docs.RenderedCode
-                     Language.PureScript.Docs.RenderedCode.Types
-                     Language.PureScript.Docs.RenderedCode.RenderType
-                     Language.PureScript.Docs.RenderedCode.RenderKind
-                     Language.PureScript.Docs.AsMarkdown
-                     Language.PureScript.Docs.AsHtml
-                     Language.PureScript.Docs.ParseInPackage
-                     Language.PureScript.Docs.Utils.MonoidExtras
-
-                     Language.PureScript.Publish
-                     Language.PureScript.Publish.Utils
-                     Language.PureScript.Publish.ErrorsWarnings
-                     Language.PureScript.Publish.BoxesHelpers
-
-                     Language.PureScript.Ide
-                     Language.PureScript.Ide.CaseSplit
-                     Language.PureScript.Ide.Command
-                     Language.PureScript.Ide.Completion
-                     Language.PureScript.Ide.Externs
-                     Language.PureScript.Ide.Error
-                     Language.PureScript.Ide.Filter
-                     Language.PureScript.Ide.Imports
-                     Language.PureScript.Ide.Logging
-                     Language.PureScript.Ide.Matcher
-                     Language.PureScript.Ide.Pursuit
-                     Language.PureScript.Ide.Rebuild
-                     Language.PureScript.Ide.Reexports
-                     Language.PureScript.Ide.SourceFile
-                     Language.PureScript.Ide.State
-                     Language.PureScript.Ide.Types
-                     Language.PureScript.Ide.Util
-                     Language.PureScript.Ide.Watcher
-
-                     Language.PureScript.Interactive
-                     Language.PureScript.Interactive.Types
-                     Language.PureScript.Interactive.Parser
-                     Language.PureScript.Interactive.Directive
-                     Language.PureScript.Interactive.Completion
-                     Language.PureScript.Interactive.IO
-                     Language.PureScript.Interactive.Message
-                     Language.PureScript.Interactive.Module
-                     Language.PureScript.Interactive.Printer
-
-                     Control.Monad.Logger
-                     Control.Monad.Supply
-                     Control.Monad.Supply.Class
-
-                     System.IO.UTF8
-
-    extensions:      ConstraintKinds
-                     DataKinds
-                     DeriveFunctor
-                     EmptyDataDecls
-                     FlexibleContexts
-                     KindSignatures
-                     LambdaCase
-                     MultiParamTypeClasses
-                     NoImplicitPrelude
-                     PatternGuards
-                     PatternSynonyms
-                     RankNTypes
-                     RecordWildCards
-                     OverloadedStrings
-                     ScopedTypeVariables
-                     TupleSections
-                     ViewPatterns
-    exposed: True
-    buildable: True
-    hs-source-dirs: src
-    other-modules: Paths_purescript
-    ghc-options: -Wall -O2
-
-executable purs
-    build-depends: base >=4 && <5,
-                   aeson >= 0.8 && < 1.1,
-                   ansi-terminal >= 0.6.2 && < 0.7,
-                   ansi-wl-pprint -any,
-                   base-compat >=0.6.0,
-                   blaze-html -any,
-                   boxes >= 0.1.4 && < 0.2.0,
-                   bytestring -any,
-                   containers -any,
-                   directory -any,
-                   file-embed -any,
-                   filepath -any,
-                   Glob >= 0.7 && < 0.8,
-                   haskeline >= 0.7.0.0,
-                   http-types == 0.9.*,
-                   monad-logger -any,
-                   mtl -any,
-                   network -any,
-                   optparse-applicative >= 0.13.0,
-                   parsec -any,
-                   process -any,
-                   protolude >= 0.1.6,
-                   purescript -any,
-                   sourcemap >= 0.1.6,
-                   split -any,
-                   stm >= 0.2.4.0,
-                   text -any,
-                   time -any,
-                   transformers -any,
-                   transformers-compat -any,
-                   utf8-string >= 1 && < 2,
-                   wai == 3.*,
-                   wai-websockets == 3.*,
-                   warp == 3.*,
-                   websockets >= 0.9 && <0.11
-    main-is: Main.hs
-    buildable: True
-    hs-source-dirs: app
-    other-modules: Paths_purescript
-                   Command.Bundle
-                   Command.Compile
-                   Command.Docs
-                   Command.Docs.Ctags
-                   Command.Docs.Etags
-                   Command.Docs.Tags
-                   Command.Docs.Html
-                   Command.Hierarchy
-                   Command.Ide
-                   Command.Publish
-                   Command.REPL
-                   Version
-    ghc-options: -Wall -O2 -fno-warn-unused-do-bind -threaded -rtsopts "-with-rtsopts=-N"
-
-    if flag(release)
-      cpp-options: -DRELEASE
-    else
-      build-depends: gitrev >= 1.2.0 && <1.3
-
-test-suite tests
-    build-depends: base >=4 && <5,
-                   purescript -any,
-                   aeson -any,
-                   aeson-better-errors -any,
-                   base-compat -any,
-                   bower-json -any,
-                   boxes -any,
-                   bytestring -any,
-                   containers -any,
-                   directory -any,
-                   filepath -any,
-                   Glob -any,
-                   haskeline >= 0.7.0.0,
-                   hspec -any,
-                   hspec-discover -any,
-                   HUnit -any,
-                   lens -any,
-                   monad-logger -any,
-                   mtl -any,
-                   optparse-applicative -any,
-                   parsec -any,
-                   process -any,
-                   protolude >= 0.1.6,
-                   silently -any,
-                   stm -any,
-                   text -any,
-                   time -any,
-                   transformers -any,
-                   transformers-compat -any,
-                   utf8-string -any,
-                   vector -any
-    ghc-options: -Wall
-    type: exitcode-stdio-1.0
-    main-is: Main.hs
-    other-modules: TestUtils
-                   TestCompiler
-                   TestDocs
-                   TestPrimDocs
-                   TestPscPublish
-                   TestPsci
-                   TestPsci.CommandTest
-                   TestPsci.CompletionTest
-                   TestPsci.TestEnv
-                   TestPscIde
-                   PscIdeSpec
-                   Language.PureScript.Ide.Test
-                   Language.PureScript.Ide.FilterSpec
-                   Language.PureScript.Ide.ImportsSpec
-                   Language.PureScript.Ide.MatcherSpec
-                   Language.PureScript.Ide.RebuildSpec
-                   Language.PureScript.Ide.ReexportsSpec
-                   Language.PureScript.Ide.SourceFileSpec
-                   Language.PureScript.Ide.StateSpec
-    buildable: True
-    hs-source-dirs: tests
+-- This file has been generated from package.yaml by hpack version 0.15.0.
+--
+-- see: https://github.com/sol/hpack
+
+name:           purescript
+version:        0.11.2
+cabal-version:  >= 1.10
+build-type:     Simple
+license:        BSD3
+license-file:   LICENSE
+copyright:      (c) 2013-16 Phil Freeman, (c) 2014-16 Gary Burgess
+maintainer:     Phil Freeman <paf31@cantab.net>
+stability:      experimental
+homepage:       http://www.purescript.org/
+bug-reports:    https://github.com/purescript/purescript.git/issues
+synopsis:       PureScript Programming Language Compiler
+description:    A small strongly, statically typed programming language with expressive types, inspired by Haskell and compiling to JavaScript.
+category:       Language
+author:         Phil Freeman <paf31@cantab.net>, Gary Burgess <gary.burgess@gmail.com>, Hardy Jones <jones3.hardy@gmail.com>, Harry Garrood <harry@garrood.me>, Christoph Hegemann <christoph.hegemann1337@gmail.com>
+
+
+extra-source-files:
+      app/static/index.html
+      app/static/index.js
+      app/static/normalize.css
+      app/static/pursuit.css
+      CONTRIBUTING.md
+      CONTRIBUTORS.md
+      examples/docs/bower.json
+      examples/docs/bower_components/purescript-prelude/src/Prelude.purs
+      examples/docs/resolutions.json
+      examples/docs/src/Clash.purs
+      examples/docs/src/Clash1.purs
+      examples/docs/src/Clash1a.purs
+      examples/docs/src/Clash2.purs
+      examples/docs/src/Clash2a.purs
+      examples/docs/src/ConstrainedArgument.purs
+      examples/docs/src/DocComments.purs
+      examples/docs/src/DuplicateNames.purs
+      examples/docs/src/Example.purs
+      examples/docs/src/Example2.purs
+      examples/docs/src/ExplicitTypeSignatures.purs
+      examples/docs/src/ImportedTwice.purs
+      examples/docs/src/ImportedTwiceA.purs
+      examples/docs/src/ImportedTwiceB.purs
+      examples/docs/src/MultiVirtual.purs
+      examples/docs/src/MultiVirtual1.purs
+      examples/docs/src/MultiVirtual2.purs
+      examples/docs/src/MultiVirtual3.purs
+      examples/docs/src/NewOperators.purs
+      examples/docs/src/NewOperators2.purs
+      examples/docs/src/NotAllCtors.purs
+      examples/docs/src/ReExportedTypeClass.purs
+      examples/docs/src/SolitaryTypeClassMember.purs
+      examples/docs/src/SomeTypeClass.purs
+      examples/docs/src/Transitive1.purs
+      examples/docs/src/Transitive2.purs
+      examples/docs/src/Transitive3.purs
+      examples/docs/src/TypeClassWithFunDeps.purs
+      examples/docs/src/TypeClassWithoutMembers.purs
+      examples/docs/src/TypeClassWithoutMembersIntermediate.purs
+      examples/docs/src/TypeOpAliases.purs
+      examples/docs/src/UTF8.purs
+      examples/docs/src/Virtual.purs
+      examples/failing/1071.purs
+      examples/failing/1169.purs
+      examples/failing/1175.purs
+      examples/failing/1310.purs
+      examples/failing/1570.purs
+      examples/failing/1733.purs
+      examples/failing/1733/Thingy.purs
+      examples/failing/1825.purs
+      examples/failing/1881.purs
+      examples/failing/2128-class.purs
+      examples/failing/2128-instance.purs
+      examples/failing/2378.purs
+      examples/failing/2378/Lib.purs
+      examples/failing/2379.purs
+      examples/failing/2379/Lib.purs
+      examples/failing/2434.purs
+      examples/failing/2534.purs
+      examples/failing/2542.purs
+      examples/failing/2567.purs
+      examples/failing/2601.purs
+      examples/failing/2616.purs
+      examples/failing/365.purs
+      examples/failing/438.purs
+      examples/failing/881.purs
+      examples/failing/AnonArgument1.purs
+      examples/failing/AnonArgument2.purs
+      examples/failing/AnonArgument3.purs
+      examples/failing/ArgLengthMismatch.purs
+      examples/failing/Arrays.purs
+      examples/failing/ArrayType.purs
+      examples/failing/BindInDo-2.purs
+      examples/failing/BindInDo.purs
+      examples/failing/CannotDeriveNewtypeForData.purs
+      examples/failing/CaseBinderLengthsDiffer.purs
+      examples/failing/CaseDoesNotMatchAllConstructorArgs.purs
+      examples/failing/ConflictingExports.purs
+      examples/failing/ConflictingExports/A.purs
+      examples/failing/ConflictingExports/B.purs
+      examples/failing/ConflictingImports.purs
+      examples/failing/ConflictingImports/A.purs
+      examples/failing/ConflictingImports/B.purs
+      examples/failing/ConflictingImports2.purs
+      examples/failing/ConflictingImports2/A.purs
+      examples/failing/ConflictingImports2/B.purs
+      examples/failing/ConflictingQualifiedImports.purs
+      examples/failing/ConflictingQualifiedImports/A.purs
+      examples/failing/ConflictingQualifiedImports/B.purs
+      examples/failing/ConflictingQualifiedImports2.purs
+      examples/failing/ConflictingQualifiedImports2/A.purs
+      examples/failing/ConflictingQualifiedImports2/B.purs
+      examples/failing/ConstraintFailure.purs
+      examples/failing/ConstraintInference.purs
+      examples/failing/DctorOperatorAliasExport.purs
+      examples/failing/DeclConflictClassCtor.purs
+      examples/failing/DeclConflictClassSynonym.purs
+      examples/failing/DeclConflictClassType.purs
+      examples/failing/DeclConflictCtorClass.purs
+      examples/failing/DeclConflictCtorCtor.purs
+      examples/failing/DeclConflictDuplicateCtor.purs
+      examples/failing/DeclConflictSynonymClass.purs
+      examples/failing/DeclConflictSynonymType.purs
+      examples/failing/DeclConflictTypeClass.purs
+      examples/failing/DeclConflictTypeSynonym.purs
+      examples/failing/DeclConflictTypeType.purs
+      examples/failing/DiffKindsSameName.purs
+      examples/failing/DiffKindsSameName/LibA.purs
+      examples/failing/DiffKindsSameName/LibB.purs
+      examples/failing/Do.purs
+      examples/failing/DoNotSuggestComposition.purs
+      examples/failing/DoNotSuggestComposition2.purs
+      examples/failing/DuplicateDeclarationsInLet.purs
+      examples/failing/DuplicateModule.purs
+      examples/failing/DuplicateModule/M1.purs
+      examples/failing/DuplicateProperties.purs
+      examples/failing/DuplicateTypeVars.purs
+      examples/failing/Eff.purs
+      examples/failing/EmptyCase.purs
+      examples/failing/EmptyClass.purs
+      examples/failing/EmptyDo.purs
+      examples/failing/ExportConflictClass.purs
+      examples/failing/ExportConflictClass/A.purs
+      examples/failing/ExportConflictClass/B.purs
+      examples/failing/ExportConflictCtor.purs
+      examples/failing/ExportConflictCtor/A.purs
+      examples/failing/ExportConflictCtor/B.purs
+      examples/failing/ExportConflictType.purs
+      examples/failing/ExportConflictType/A.purs
+      examples/failing/ExportConflictType/B.purs
+      examples/failing/ExportConflictTypeOp.purs
+      examples/failing/ExportConflictTypeOp/A.purs
+      examples/failing/ExportConflictTypeOp/B.purs
+      examples/failing/ExportConflictValue.purs
+      examples/failing/ExportConflictValue/A.purs
+      examples/failing/ExportConflictValue/B.purs
+      examples/failing/ExportConflictValueOp.purs
+      examples/failing/ExportConflictValueOp/A.purs
+      examples/failing/ExportConflictValueOp/B.purs
+      examples/failing/ExportExplicit.purs
+      examples/failing/ExportExplicit1.purs
+      examples/failing/ExportExplicit1/M1.purs
+      examples/failing/ExportExplicit2.purs
+      examples/failing/ExportExplicit3.purs
+      examples/failing/ExportExplicit3/M1.purs
+      examples/failing/ExtraRecordField.purs
+      examples/failing/Foldable.purs
+      examples/failing/Generalization1.purs
+      examples/failing/Generalization2.purs
+      examples/failing/ImportExplicit.purs
+      examples/failing/ImportExplicit/M1.purs
+      examples/failing/ImportExplicit2.purs
+      examples/failing/ImportExplicit2/M1.purs
+      examples/failing/ImportHidingModule.purs
+      examples/failing/ImportHidingModule/A.purs
+      examples/failing/ImportHidingModule/B.purs
+      examples/failing/ImportModule.purs
+      examples/failing/ImportModule/M2.purs
+      examples/failing/InfiniteKind.purs
+      examples/failing/InfiniteType.purs
+      examples/failing/InstanceExport.purs
+      examples/failing/InstanceExport/InstanceExport.purs
+      examples/failing/IntOutOfRange.purs
+      examples/failing/InvalidDerivedInstance.purs
+      examples/failing/InvalidDerivedInstance2.purs
+      examples/failing/InvalidOperatorInBinder.purs
+      examples/failing/KindError.purs
+      examples/failing/KindStar.purs
+      examples/failing/LeadingZeros1.purs
+      examples/failing/LeadingZeros2.purs
+      examples/failing/Let.purs
+      examples/failing/LetPatterns1.purs
+      examples/failing/LetPatterns2.purs
+      examples/failing/LetPatterns3.purs
+      examples/failing/LetPatterns4.purs
+      examples/failing/MissingClassExport.purs
+      examples/failing/MissingClassMemberExport.purs
+      examples/failing/MissingRecordField.purs
+      examples/failing/MPTCs.purs
+      examples/failing/MultipleErrors.purs
+      examples/failing/MultipleErrors2.purs
+      examples/failing/MultipleTypeOpFixities.purs
+      examples/failing/MultipleValueOpFixities.purs
+      examples/failing/MutRec.purs
+      examples/failing/MutRec2.purs
+      examples/failing/NewtypeInstance.purs
+      examples/failing/NewtypeInstance2.purs
+      examples/failing/NewtypeInstance3.purs
+      examples/failing/NewtypeInstance4.purs
+      examples/failing/NewtypeInstance5.purs
+      examples/failing/NewtypeInstance6.purs
+      examples/failing/NewtypeMultiArgs.purs
+      examples/failing/NewtypeMultiCtor.purs
+      examples/failing/NonExhaustivePatGuard.purs
+      examples/failing/NonWildcardNewtypeInstance.purs
+      examples/failing/NullaryAbs.purs
+      examples/failing/Object.purs
+      examples/failing/OperatorAliasNoExport.purs
+      examples/failing/OperatorSections.purs
+      examples/failing/OrphanInstance.purs
+      examples/failing/OrphanInstance/Class.purs
+      examples/failing/OrphanInstanceFunDepCycle.purs
+      examples/failing/OrphanInstanceFunDepCycle/Lib.purs
+      examples/failing/OrphanInstanceNullary.purs
+      examples/failing/OrphanInstanceNullary/Lib.purs
+      examples/failing/OrphanInstanceWithDetermined.purs
+      examples/failing/OrphanInstanceWithDetermined/Lib.purs
+      examples/failing/OrphanTypeDecl.purs
+      examples/failing/OverlappingArguments.purs
+      examples/failing/OverlappingBinders.purs
+      examples/failing/OverlappingVars.purs
+      examples/failing/ProgrammableTypeErrors.purs
+      examples/failing/ProgrammableTypeErrorsTypeString.purs
+      examples/failing/Rank2Types.purs
+      examples/failing/RequiredHiddenType.purs
+      examples/failing/Reserved.purs
+      examples/failing/RowConstructors1.purs
+      examples/failing/RowConstructors2.purs
+      examples/failing/RowConstructors3.purs
+      examples/failing/RowInInstanceNotDetermined0.purs
+      examples/failing/RowInInstanceNotDetermined1.purs
+      examples/failing/RowInInstanceNotDetermined2.purs
+      examples/failing/SkolemEscape.purs
+      examples/failing/SkolemEscape2.purs
+      examples/failing/SuggestComposition.purs
+      examples/failing/Superclasses1.purs
+      examples/failing/Superclasses2.purs
+      examples/failing/Superclasses3.purs
+      examples/failing/Superclasses5.purs
+      examples/failing/TooFewClassInstanceArgs.purs
+      examples/failing/TopLevelCaseNoArgs.purs
+      examples/failing/TransitiveDctorExport.purs
+      examples/failing/TransitiveSynonymExport.purs
+      examples/failing/TypeClasses2.purs
+      examples/failing/TypeClassInstances.purs
+      examples/failing/TypedBinders.purs
+      examples/failing/TypedBinders2.purs
+      examples/failing/TypedBinders3.purs
+      examples/failing/TypedHole.purs
+      examples/failing/TypeError.purs
+      examples/failing/TypeOperatorAliasNoExport.purs
+      examples/failing/TypeSynonyms.purs
+      examples/failing/TypeSynonyms2.purs
+      examples/failing/TypeSynonyms3.purs
+      examples/failing/TypeSynonyms4.purs
+      examples/failing/TypeSynonyms5.purs
+      examples/failing/TypeWildcards1.purs
+      examples/failing/TypeWildcards2.purs
+      examples/failing/TypeWildcards3.purs
+      examples/failing/UnderscoreModuleName.purs
+      examples/failing/UnknownType.purs
+      examples/failing/UnusableTypeClassMethod.purs
+      examples/failing/UnusableTypeClassMethodConflictingIdent.purs
+      examples/failing/UnusableTypeClassMethodSynonym.purs
+      examples/passing/1110.purs
+      examples/passing/1185.purs
+      examples/passing/1335.purs
+      examples/passing/1570.purs
+      examples/passing/1664.purs
+      examples/passing/1697.purs
+      examples/passing/1807.purs
+      examples/passing/1881.purs
+      examples/passing/1991.purs
+      examples/passing/2018.purs
+      examples/passing/2018/A.purs
+      examples/passing/2018/B.purs
+      examples/passing/2049.purs
+      examples/passing/2136.purs
+      examples/passing/2138.purs
+      examples/passing/2138/Lib.purs
+      examples/passing/2172.js
+      examples/passing/2172.purs
+      examples/passing/2252.purs
+      examples/passing/2288.purs
+      examples/passing/2378.purs
+      examples/passing/2438.purs
+      examples/passing/2609.purs
+      examples/passing/2609/Eg.purs
+      examples/passing/2616.purs
+      examples/passing/2626.purs
+      examples/passing/2663.purs
+      examples/passing/2689.purs
+      examples/passing/2695.purs
+      examples/passing/2756.purs
+      examples/passing/2787.purs
+      examples/passing/2795.purs
+      examples/passing/652.purs
+      examples/passing/810.purs
+      examples/passing/862.purs
+      examples/passing/922.purs
+      examples/passing/Applicative.purs
+      examples/passing/ArrayType.purs
+      examples/passing/Auto.purs
+      examples/passing/AutoPrelude.purs
+      examples/passing/AutoPrelude2.purs
+      examples/passing/BindersInFunctions.purs
+      examples/passing/BindingGroups.purs
+      examples/passing/BlockString.purs
+      examples/passing/CaseInDo.purs
+      examples/passing/CaseInputWildcard.purs
+      examples/passing/CaseMultipleExpressions.purs
+      examples/passing/CaseStatement.purs
+      examples/passing/CheckFunction.purs
+      examples/passing/CheckSynonymBug.purs
+      examples/passing/CheckTypeClass.purs
+      examples/passing/Church.purs
+      examples/passing/ClassRefSyntax.purs
+      examples/passing/ClassRefSyntax/Lib.purs
+      examples/passing/Collatz.purs
+      examples/passing/Comparisons.purs
+      examples/passing/Conditional.purs
+      examples/passing/Console.purs
+      examples/passing/ConstraintInference.purs
+      examples/passing/ConstraintParens.purs
+      examples/passing/ConstraintParsingIssue.purs
+      examples/passing/ContextSimplification.purs
+      examples/passing/DataAndType.purs
+      examples/passing/DctorName.purs
+      examples/passing/DctorOperatorAlias.purs
+      examples/passing/DctorOperatorAlias/List.purs
+      examples/passing/DeepArrayBinder.purs
+      examples/passing/DeepCase.purs
+      examples/passing/DeriveNewtype.purs
+      examples/passing/DeriveWithNestedSynonyms.purs
+      examples/passing/Deriving.purs
+      examples/passing/DerivingFunctor.purs
+      examples/passing/Do.purs
+      examples/passing/Dollar.purs
+      examples/passing/DuplicateProperties.purs
+      examples/passing/Eff.purs
+      examples/passing/EmptyDataDecls.purs
+      examples/passing/EmptyRow.purs
+      examples/passing/EmptyTypeClass.purs
+      examples/passing/EntailsKindedType.purs
+      examples/passing/EqOrd.purs
+      examples/passing/ExplicitImportReExport.purs
+      examples/passing/ExplicitImportReExport/Bar.purs
+      examples/passing/ExplicitImportReExport/Foo.purs
+      examples/passing/ExplicitOperatorSections.purs
+      examples/passing/ExportedInstanceDeclarations.purs
+      examples/passing/ExportExplicit.purs
+      examples/passing/ExportExplicit/M1.purs
+      examples/passing/ExportExplicit2.purs
+      examples/passing/ExportExplicit2/M1.purs
+      examples/passing/ExtendedInfixOperators.purs
+      examples/passing/Fib.purs
+      examples/passing/FieldConsPuns.purs
+      examples/passing/FieldPuns.purs
+      examples/passing/FinalTagless.purs
+      examples/passing/ForeignKind.purs
+      examples/passing/ForeignKind/Lib.purs
+      examples/passing/FunctionalDependencies.purs
+      examples/passing/Functions.purs
+      examples/passing/Functions2.purs
+      examples/passing/FunctionScope.purs
+      examples/passing/FunWithFunDeps.js
+      examples/passing/FunWithFunDeps.purs
+      examples/passing/Generalization1.purs
+      examples/passing/GenericsRep.purs
+      examples/passing/Guards.purs
+      examples/passing/HasOwnProperty.purs
+      examples/passing/HoistError.purs
+      examples/passing/IfThenElseMaybe.purs
+      examples/passing/IfWildcard.purs
+      examples/passing/ImplicitEmptyImport.purs
+      examples/passing/Import.purs
+      examples/passing/Import/M1.purs
+      examples/passing/Import/M2.purs
+      examples/passing/ImportExplicit.purs
+      examples/passing/ImportExplicit/M1.purs
+      examples/passing/ImportHiding.purs
+      examples/passing/ImportQualified.purs
+      examples/passing/ImportQualified/M1.purs
+      examples/passing/InferRecFunWithConstrainedArgument.purs
+      examples/passing/InstanceBeforeClass.purs
+      examples/passing/IntAndChar.purs
+      examples/passing/iota.purs
+      examples/passing/JSReserved.purs
+      examples/passing/KindedType.purs
+      examples/passing/LargeSumType.purs
+      examples/passing/Let.purs
+      examples/passing/Let2.purs
+      examples/passing/LetInInstance.purs
+      examples/passing/LetPattern.purs
+      examples/passing/LiberalTypeSynonyms.purs
+      examples/passing/Match.purs
+      examples/passing/Module.purs
+      examples/passing/Module/M1.purs
+      examples/passing/Module/M2.purs
+      examples/passing/ModuleDeps.purs
+      examples/passing/ModuleDeps/M1.purs
+      examples/passing/ModuleDeps/M2.purs
+      examples/passing/ModuleDeps/M3.purs
+      examples/passing/ModuleExport.purs
+      examples/passing/ModuleExport/A.purs
+      examples/passing/ModuleExportDupes.purs
+      examples/passing/ModuleExportDupes/A.purs
+      examples/passing/ModuleExportDupes/B.purs
+      examples/passing/ModuleExportDupes/C.purs
+      examples/passing/ModuleExportExcluded.purs
+      examples/passing/ModuleExportExcluded/A.purs
+      examples/passing/ModuleExportQualified.purs
+      examples/passing/ModuleExportQualified/A.purs
+      examples/passing/ModuleExportSelf.purs
+      examples/passing/ModuleExportSelf/A.purs
+      examples/passing/Monad.purs
+      examples/passing/MonadState.purs
+      examples/passing/MPTCs.purs
+      examples/passing/MultiArgFunctions.purs
+      examples/passing/MutRec.purs
+      examples/passing/MutRec2.purs
+      examples/passing/MutRec3.purs
+      examples/passing/NakedConstraint.purs
+      examples/passing/NamedPatterns.purs
+      examples/passing/NegativeBinder.purs
+      examples/passing/NegativeIntInRange.purs
+      examples/passing/Nested.purs
+      examples/passing/NestedRecordUpdate.purs
+      examples/passing/NestedRecordUpdateWildcards.purs
+      examples/passing/NestedTypeSynonyms.purs
+      examples/passing/NestedWhere.purs
+      examples/passing/Newtype.purs
+      examples/passing/NewtypeClass.purs
+      examples/passing/NewtypeEff.purs
+      examples/passing/NewtypeInstance.purs
+      examples/passing/NewtypeWithRecordUpdate.purs
+      examples/passing/NonConflictingExports.purs
+      examples/passing/NonConflictingExports/A.purs
+      examples/passing/NonOrphanInstanceFunDepExtra.purs
+      examples/passing/NonOrphanInstanceFunDepExtra/Lib.purs
+      examples/passing/NonOrphanInstanceMulti.purs
+      examples/passing/NonOrphanInstanceMulti/Lib.purs
+      examples/passing/NumberLiterals.purs
+      examples/passing/ObjectGetter.purs
+      examples/passing/Objects.purs
+      examples/passing/ObjectSynonym.purs
+      examples/passing/ObjectUpdate.purs
+      examples/passing/ObjectUpdate2.purs
+      examples/passing/ObjectUpdater.purs
+      examples/passing/ObjectWildcards.purs
+      examples/passing/OneConstructor.purs
+      examples/passing/OperatorAlias.purs
+      examples/passing/OperatorAliasElsewhere.purs
+      examples/passing/OperatorAliasElsewhere/Def.purs
+      examples/passing/OperatorAssociativity.purs
+      examples/passing/OperatorInlining.purs
+      examples/passing/Operators.purs
+      examples/passing/Operators/Other.purs
+      examples/passing/OperatorSections.purs
+      examples/passing/OptimizerBug.purs
+      examples/passing/OptionalQualified.purs
+      examples/passing/OverlappingInstances.purs
+      examples/passing/OverlappingInstances2.purs
+      examples/passing/OverlappingInstances3.purs
+      examples/passing/ParensInTypedBinder.purs
+      examples/passing/PartialFunction.purs
+      examples/passing/Patterns.purs
+      examples/passing/PendingConflictingImports.purs
+      examples/passing/PendingConflictingImports/A.purs
+      examples/passing/PendingConflictingImports/B.purs
+      examples/passing/PendingConflictingImports2.purs
+      examples/passing/PendingConflictingImports2/A.purs
+      examples/passing/Person.purs
+      examples/passing/PolyLabels.js
+      examples/passing/PolyLabels.purs
+      examples/passing/PrimedTypeName.purs
+      examples/passing/QualifiedNames.purs
+      examples/passing/QualifiedNames/Either.purs
+      examples/passing/QualifiedQualifiedImports.purs
+      examples/passing/Rank2Data.purs
+      examples/passing/Rank2Object.purs
+      examples/passing/Rank2Types.purs
+      examples/passing/Rank2TypeSynonym.purs
+      examples/passing/RebindableSyntax.purs
+      examples/passing/Recursion.purs
+      examples/passing/RedefinedFixity.purs
+      examples/passing/RedefinedFixity/M1.purs
+      examples/passing/RedefinedFixity/M2.purs
+      examples/passing/RedefinedFixity/M3.purs
+      examples/passing/ReExportQualified.purs
+      examples/passing/ReExportQualified/A.purs
+      examples/passing/ReExportQualified/B.purs
+      examples/passing/ReExportQualified/C.purs
+      examples/passing/ReservedWords.purs
+      examples/passing/ResolvableScopeConflict.purs
+      examples/passing/ResolvableScopeConflict/A.purs
+      examples/passing/ResolvableScopeConflict/B.purs
+      examples/passing/ResolvableScopeConflict2.purs
+      examples/passing/ResolvableScopeConflict2/A.purs
+      examples/passing/ResolvableScopeConflict3.purs
+      examples/passing/ResolvableScopeConflict3/A.purs
+      examples/passing/RowConstructors.purs
+      examples/passing/RowInInstanceHeadDetermined.purs
+      examples/passing/RowPolyInstanceContext.purs
+      examples/passing/RowsInInstanceContext.purs
+      examples/passing/RowUnion.js
+      examples/passing/RowUnion.purs
+      examples/passing/RuntimeScopeIssue.purs
+      examples/passing/s.purs
+      examples/passing/ScopedTypeVariables.purs
+      examples/passing/Sequence.purs
+      examples/passing/SequenceDesugared.purs
+      examples/passing/ShadowedModuleName.purs
+      examples/passing/ShadowedModuleName/Test.purs
+      examples/passing/ShadowedName.purs
+      examples/passing/ShadowedRename.purs
+      examples/passing/ShadowedTCO.purs
+      examples/passing/ShadowedTCOLet.purs
+      examples/passing/SignedNumericLiterals.purs
+      examples/passing/SolvingAppendSymbol.purs
+      examples/passing/SolvingCompareSymbol.purs
+      examples/passing/SolvingIsSymbol.purs
+      examples/passing/SolvingIsSymbol/Lib.purs
+      examples/passing/Stream.purs
+      examples/passing/StringEdgeCases.purs
+      examples/passing/StringEdgeCases/Records.purs
+      examples/passing/StringEdgeCases/Symbols.purs
+      examples/passing/StringEscapes.purs
+      examples/passing/Superclasses1.purs
+      examples/passing/Superclasses3.purs
+      examples/passing/TailCall.purs
+      examples/passing/TCO.purs
+      examples/passing/TCOCase.purs
+      examples/passing/Tick.purs
+      examples/passing/TopLevelCase.purs
+      examples/passing/TransitiveImport.purs
+      examples/passing/TransitiveImport/Middle.purs
+      examples/passing/TransitiveImport/Test.purs
+      examples/passing/TypeClasses.purs
+      examples/passing/TypeClassesInOrder.purs
+      examples/passing/TypeClassesWithOverlappingTypeVariables.purs
+      examples/passing/TypeClassMemberOrderChange.purs
+      examples/passing/TypedBinders.purs
+      examples/passing/TypeDecl.purs
+      examples/passing/TypedWhere.purs
+      examples/passing/TypeOperators.purs
+      examples/passing/TypeOperators/A.purs
+      examples/passing/TypeSynonymInData.purs
+      examples/passing/TypeSynonyms.purs
+      examples/passing/TypeWildcards.purs
+      examples/passing/TypeWildcardsRecordExtension.purs
+      examples/passing/TypeWithoutParens.purs
+      examples/passing/TypeWithoutParens/Lib.purs
+      examples/passing/UnderscoreIdent.purs
+      examples/passing/UnicodeIdentifier.purs
+      examples/passing/UnicodeOperators.purs
+      examples/passing/UnicodeType.purs
+      examples/passing/UnifyInTypeInstanceLookup.purs
+      examples/passing/Unit.purs
+      examples/passing/UnknownInTypeClassLookup.purs
+      examples/passing/UntupledConstraints.purs
+      examples/passing/UsableTypeClassMethods.purs
+      examples/passing/UTF8Sourcefile.purs
+      examples/passing/Where.purs
+      examples/passing/WildcardInInstance.purs
+      examples/passing/WildcardType.purs
+      examples/psci/BasicEval.purs
+      examples/psci/Multiline.purs
+      examples/warning/2140.purs
+      examples/warning/2383.purs
+      examples/warning/2411.purs
+      examples/warning/2542.purs
+      examples/warning/CustomWarning.purs
+      examples/warning/DuplicateExportRef.purs
+      examples/warning/DuplicateImport.purs
+      examples/warning/DuplicateImportRef.purs
+      examples/warning/DuplicateSelectiveImport.purs
+      examples/warning/HidingImport.purs
+      examples/warning/ImplicitImport.purs
+      examples/warning/ImplicitQualifiedImport.purs
+      examples/warning/MissingTypeDeclaration.purs
+      examples/warning/OverlappingInstances.purs
+      examples/warning/OverlappingPattern.purs
+      examples/warning/ScopeShadowing.purs
+      examples/warning/ShadowedBinderPatternGuard.purs
+      examples/warning/ShadowedNameParens.purs
+      examples/warning/ShadowedTypeVar.purs
+      examples/warning/UnnecessaryFFIModule.js
+      examples/warning/UnnecessaryFFIModule.purs
+      examples/warning/UnusedDctorExplicitImport.purs
+      examples/warning/UnusedDctorImportAll.purs
+      examples/warning/UnusedDctorImportExplicit.purs
+      examples/warning/UnusedExplicitImport.purs
+      examples/warning/UnusedExplicitImportTypeOp.purs
+      examples/warning/UnusedExplicitImportTypeOp/Lib.purs
+      examples/warning/UnusedExplicitImportValOp.purs
+      examples/warning/UnusedFFIImplementations.js
+      examples/warning/UnusedFFIImplementations.purs
+      examples/warning/UnusedImport.purs
+      examples/warning/UnusedTypeVar.purs
+      examples/warning/WildcardInferredType.purs
+      INSTALL.md
+      README.md
+      stack.yaml
+      tests/support/bower.json
+      tests/support/package.json
+      tests/support/prelude-resolutions.json
+      tests/support/psci/Sample.purs
+      tests/support/pscide/src/ImportsSpec.purs
+      tests/support/pscide/src/ImportsSpec1.purs
+      tests/support/pscide/src/MatcherSpec.purs
+      tests/support/pscide/src/RebuildSpecDep.purs
+      tests/support/pscide/src/RebuildSpecSingleModule.fail
+      tests/support/pscide/src/RebuildSpecSingleModule.purs
+      tests/support/pscide/src/RebuildSpecWithDeps.purs
+      tests/support/pscide/src/RebuildSpecWithForeign.js
+      tests/support/pscide/src/RebuildSpecWithForeign.purs
+      tests/support/pscide/src/RebuildSpecWithHiddenIdent.purs
+      tests/support/pscide/src/RebuildSpecWithMissingForeign.fail
+      tests/support/setup-win.cmd
+
+source-repository head
+    type: git
+    location: https://github.com/purescript/purescript.git
+
+flag release
+    description: Mark this build as a release build: prevents inclusion of extra info e.g. commit SHA in --version output)
+
+    manual: False
+    default: False
+
+library
+    build-depends:
+          aeson >=0.8 && <1.1
+        , aeson-better-errors >=0.8
+        , ansi-terminal >=0.6.2 && <0.7
+        , base >=4.8 && <5
+        , base-compat >=0.6.0
+        , blaze-html >=0.8.1 && <0.9
+        , bower-json >=1.0.0.1 && <1.1
+        , boxes >=0.1.4 && <0.2.0
+        , bytestring
+        , cheapskate >=0.1 && <0.2
+        , clock
+        , containers
+        , data-ordlist >=0.4.7.0
+        , deepseq
+        , directory >=1.2
+        , dlist
+        , edit-distance
+        , filepath
+        , fsnotify >=0.2.1
+        , Glob >=0.7 && <0.8
+        , haskeline >=0.7.0.0
+        , http-client >=0.4.30 && <0.6.0
+        , http-types
+        , language-javascript >=0.6.0.9 && <0.7
+        , lens ==4.*
+        , lifted-base >=0.2.3 && <0.2.4
+        , monad-control >=1.0.0.0 && <1.1
+        , monad-logger >=0.3 && <0.4
+        , mtl >=2.1.0 && <2.3.0
+        , parallel >=3.2 && <3.3
+        , parsec >=3.1.10
+        , pattern-arrows >=0.0.2 && <0.1
+        , pipes >=4.0.0 && <4.4.0
+        , pipes-http
+        , process >=1.2.0 && <1.5
+        , protolude >=0.1.6
+        , regex-tdfa
+        , safe >=0.3.9 && <0.4
+        , scientific >=0.3.4.9 && <0.4
+        , semigroups >=0.16.2 && <0.19
+        , sourcemap >=0.1.6
+        , spdx ==0.2.*
+        , split
+        , stm >=0.2.4.0
+        , syb
+        , text
+        , time
+        , transformers >=0.3.0 && <0.6
+        , transformers-base >=0.4.0 && <0.5
+        , transformers-compat >=0.3.0
+        , unordered-containers
+        , utf8-string >=1 && <2
+        , vector
+    exposed-modules:
+          Control.Monad.Logger
+          Control.Monad.Supply
+          Control.Monad.Supply.Class
+          Language.PureScript
+          Language.PureScript.AST
+          Language.PureScript.AST.Binders
+          Language.PureScript.AST.Declarations
+          Language.PureScript.AST.Exported
+          Language.PureScript.AST.Literals
+          Language.PureScript.AST.Operators
+          Language.PureScript.AST.SourcePos
+          Language.PureScript.AST.Traversals
+          Language.PureScript.Bundle
+          Language.PureScript.CodeGen
+          Language.PureScript.CodeGen.JS
+          Language.PureScript.CodeGen.JS.Common
+          Language.PureScript.CodeGen.JS.Printer
+          Language.PureScript.Comments
+          Language.PureScript.Constants
+          Language.PureScript.CoreFn
+          Language.PureScript.CoreFn.Ann
+          Language.PureScript.CoreFn.Binders
+          Language.PureScript.CoreFn.Desugar
+          Language.PureScript.CoreFn.Expr
+          Language.PureScript.CoreFn.Meta
+          Language.PureScript.CoreFn.Module
+          Language.PureScript.CoreFn.ToJSON
+          Language.PureScript.CoreFn.Traversals
+          Language.PureScript.CoreImp
+          Language.PureScript.CoreImp.AST
+          Language.PureScript.CoreImp.Optimizer
+          Language.PureScript.CoreImp.Optimizer.Blocks
+          Language.PureScript.CoreImp.Optimizer.Common
+          Language.PureScript.CoreImp.Optimizer.Inliner
+          Language.PureScript.CoreImp.Optimizer.MagicDo
+          Language.PureScript.CoreImp.Optimizer.TCO
+          Language.PureScript.CoreImp.Optimizer.Unused
+          Language.PureScript.Crash
+          Language.PureScript.Docs
+          Language.PureScript.Docs.AsHtml
+          Language.PureScript.Docs.AsMarkdown
+          Language.PureScript.Docs.Convert
+          Language.PureScript.Docs.Convert.ReExports
+          Language.PureScript.Docs.Convert.Single
+          Language.PureScript.Docs.ParseInPackage
+          Language.PureScript.Docs.Prim
+          Language.PureScript.Docs.Render
+          Language.PureScript.Docs.RenderedCode
+          Language.PureScript.Docs.RenderedCode.RenderKind
+          Language.PureScript.Docs.RenderedCode.RenderType
+          Language.PureScript.Docs.RenderedCode.Types
+          Language.PureScript.Docs.Types
+          Language.PureScript.Docs.Utils.MonoidExtras
+          Language.PureScript.Environment
+          Language.PureScript.Errors
+          Language.PureScript.Errors.JSON
+          Language.PureScript.Externs
+          Language.PureScript.Ide
+          Language.PureScript.Ide.CaseSplit
+          Language.PureScript.Ide.Command
+          Language.PureScript.Ide.Completion
+          Language.PureScript.Ide.Error
+          Language.PureScript.Ide.Externs
+          Language.PureScript.Ide.Filter
+          Language.PureScript.Ide.Imports
+          Language.PureScript.Ide.Logging
+          Language.PureScript.Ide.Matcher
+          Language.PureScript.Ide.Pursuit
+          Language.PureScript.Ide.Rebuild
+          Language.PureScript.Ide.Reexports
+          Language.PureScript.Ide.SourceFile
+          Language.PureScript.Ide.State
+          Language.PureScript.Ide.Types
+          Language.PureScript.Ide.Util
+          Language.PureScript.Ide.Watcher
+          Language.PureScript.Interactive
+          Language.PureScript.Interactive.Completion
+          Language.PureScript.Interactive.Directive
+          Language.PureScript.Interactive.IO
+          Language.PureScript.Interactive.Message
+          Language.PureScript.Interactive.Module
+          Language.PureScript.Interactive.Parser
+          Language.PureScript.Interactive.Printer
+          Language.PureScript.Interactive.Types
+          Language.PureScript.Kinds
+          Language.PureScript.Label
+          Language.PureScript.Linter
+          Language.PureScript.Linter.Exhaustive
+          Language.PureScript.Linter.Imports
+          Language.PureScript.Make
+          Language.PureScript.ModuleDependencies
+          Language.PureScript.Names
+          Language.PureScript.Options
+          Language.PureScript.Parser
+          Language.PureScript.Parser.Common
+          Language.PureScript.Parser.Declarations
+          Language.PureScript.Parser.Kinds
+          Language.PureScript.Parser.Lexer
+          Language.PureScript.Parser.State
+          Language.PureScript.Parser.Types
+          Language.PureScript.Pretty
+          Language.PureScript.Pretty.Common
+          Language.PureScript.Pretty.Kinds
+          Language.PureScript.Pretty.Types
+          Language.PureScript.Pretty.Values
+          Language.PureScript.PSString
+          Language.PureScript.Publish
+          Language.PureScript.Publish.BoxesHelpers
+          Language.PureScript.Publish.ErrorsWarnings
+          Language.PureScript.Publish.Utils
+          Language.PureScript.Renamer
+          Language.PureScript.Sugar
+          Language.PureScript.Sugar.BindingGroups
+          Language.PureScript.Sugar.CaseDeclarations
+          Language.PureScript.Sugar.DoNotation
+          Language.PureScript.Sugar.LetPattern
+          Language.PureScript.Sugar.Names
+          Language.PureScript.Sugar.Names.Common
+          Language.PureScript.Sugar.Names.Env
+          Language.PureScript.Sugar.Names.Exports
+          Language.PureScript.Sugar.Names.Imports
+          Language.PureScript.Sugar.ObjectWildcards
+          Language.PureScript.Sugar.Operators
+          Language.PureScript.Sugar.Operators.Binders
+          Language.PureScript.Sugar.Operators.Common
+          Language.PureScript.Sugar.Operators.Expr
+          Language.PureScript.Sugar.Operators.Types
+          Language.PureScript.Sugar.TypeClasses
+          Language.PureScript.Sugar.TypeClasses.Deriving
+          Language.PureScript.Sugar.TypeDeclarations
+          Language.PureScript.Traversals
+          Language.PureScript.TypeChecker
+          Language.PureScript.TypeChecker.Entailment
+          Language.PureScript.TypeChecker.Kinds
+          Language.PureScript.TypeChecker.Monad
+          Language.PureScript.TypeChecker.Skolems
+          Language.PureScript.TypeChecker.Subsumption
+          Language.PureScript.TypeChecker.Synonyms
+          Language.PureScript.TypeChecker.Types
+          Language.PureScript.TypeChecker.TypeSearch
+          Language.PureScript.TypeChecker.Unify
+          Language.PureScript.TypeClassDictionaries
+          Language.PureScript.Types
+          System.IO.UTF8
+    other-modules:
+          Paths_purescript
+    hs-source-dirs:
+          src
+    default-extensions: ConstraintKinds DataKinds DeriveFunctor EmptyDataDecls FlexibleContexts KindSignatures LambdaCase MultiParamTypeClasses NoImplicitPrelude PatternGuards PatternSynonyms RankNTypes RecordWildCards OverloadedStrings ScopedTypeVariables TupleSections ViewPatterns
+    default-language: Haskell2010
+    ghc-options: -Wall -O2
+
+executable purs
+    build-depends:
+          aeson >=0.8 && <1.1
+        , aeson-better-errors >=0.8
+        , ansi-terminal >=0.6.2 && <0.7
+        , base >=4.8 && <5
+        , base-compat >=0.6.0
+        , blaze-html >=0.8.1 && <0.9
+        , bower-json >=1.0.0.1 && <1.1
+        , boxes >=0.1.4 && <0.2.0
+        , bytestring
+        , cheapskate >=0.1 && <0.2
+        , clock
+        , containers
+        , data-ordlist >=0.4.7.0
+        , deepseq
+        , directory >=1.2
+        , dlist
+        , edit-distance
+        , filepath
+        , fsnotify >=0.2.1
+        , Glob >=0.7 && <0.8
+        , haskeline >=0.7.0.0
+        , http-client >=0.4.30 && <0.6.0
+        , http-types
+        , language-javascript >=0.6.0.9 && <0.7
+        , lens ==4.*
+        , lifted-base >=0.2.3 && <0.2.4
+        , monad-control >=1.0.0.0 && <1.1
+        , monad-logger >=0.3 && <0.4
+        , mtl >=2.1.0 && <2.3.0
+        , parallel >=3.2 && <3.3
+        , parsec >=3.1.10
+        , pattern-arrows >=0.0.2 && <0.1
+        , pipes >=4.0.0 && <4.4.0
+        , pipes-http
+        , process >=1.2.0 && <1.5
+        , protolude >=0.1.6
+        , regex-tdfa
+        , safe >=0.3.9 && <0.4
+        , scientific >=0.3.4.9 && <0.4
+        , semigroups >=0.16.2 && <0.19
+        , sourcemap >=0.1.6
+        , spdx ==0.2.*
+        , split
+        , stm >=0.2.4.0
+        , syb
+        , text
+        , time
+        , transformers >=0.3.0 && <0.6
+        , transformers-base >=0.4.0 && <0.5
+        , transformers-compat >=0.3.0
+        , unordered-containers
+        , utf8-string >=1 && <2
+        , vector
+        , ansi-wl-pprint
+        , file-embed
+        , network
+        , optparse-applicative >=0.13.0
+        , purescript
+        , wai ==3.*
+        , wai-websockets ==3.*
+        , warp ==3.*
+        , websockets >=0.9 && <0.11
+    if flag(release)
+        cpp-options: -DRELEASE
+    else
+        build-depends:
+              gitrev >=1.2.0 && <1.3
+    main-is: Main.hs
+    hs-source-dirs:
+          app
+    other-modules:
+          Command.Bundle
+          Command.Compile
+          Command.Docs
+          Command.Docs.Ctags
+          Command.Docs.Etags
+          Command.Docs.Html
+          Command.Docs.Tags
+          Command.Hierarchy
+          Command.Ide
+          Command.Publish
+          Command.REPL
+          Version
+    default-language: Haskell2010
+    ghc-options: -Wall -O2 -fno-warn-unused-do-bind -threaded -rtsopts -with-rtsopts=-N
+
+test-suite tests
+    build-depends:
+          aeson >=0.8 && <1.1
+        , aeson-better-errors >=0.8
+        , ansi-terminal >=0.6.2 && <0.7
+        , base >=4.8 && <5
+        , base-compat >=0.6.0
+        , blaze-html >=0.8.1 && <0.9
+        , bower-json >=1.0.0.1 && <1.1
+        , boxes >=0.1.4 && <0.2.0
+        , bytestring
+        , cheapskate >=0.1 && <0.2
+        , clock
+        , containers
+        , data-ordlist >=0.4.7.0
+        , deepseq
+        , directory >=1.2
+        , dlist
+        , edit-distance
+        , filepath
+        , fsnotify >=0.2.1
+        , Glob >=0.7 && <0.8
+        , haskeline >=0.7.0.0
+        , http-client >=0.4.30 && <0.6.0
+        , http-types
+        , language-javascript >=0.6.0.9 && <0.7
+        , lens ==4.*
+        , lifted-base >=0.2.3 && <0.2.4
+        , monad-control >=1.0.0.0 && <1.1
+        , monad-logger >=0.3 && <0.4
+        , mtl >=2.1.0 && <2.3.0
+        , parallel >=3.2 && <3.3
+        , parsec >=3.1.10
+        , pattern-arrows >=0.0.2 && <0.1
+        , pipes >=4.0.0 && <4.4.0
+        , pipes-http
+        , process >=1.2.0 && <1.5
+        , protolude >=0.1.6
+        , regex-tdfa
+        , safe >=0.3.9 && <0.4
+        , scientific >=0.3.4.9 && <0.4
+        , semigroups >=0.16.2 && <0.19
+        , sourcemap >=0.1.6
+        , spdx ==0.2.*
+        , split
+        , stm >=0.2.4.0
+        , syb
+        , text
+        , time
+        , transformers >=0.3.0 && <0.6
+        , transformers-base >=0.4.0 && <0.5
+        , transformers-compat >=0.3.0
+        , unordered-containers
+        , utf8-string >=1 && <2
+        , vector
+        , purescript
+        , hspec
+        , hspec-discover
+        , HUnit
+        , silently
+    ghc-options: -Wall
+    type: exitcode-stdio-1.0
+    main-is: Main.hs
+    other-modules:
+          Language.PureScript.Ide.FilterSpec
+          Language.PureScript.Ide.ImportsSpec
+          Language.PureScript.Ide.MatcherSpec
+          Language.PureScript.Ide.RebuildSpec
+          Language.PureScript.Ide.ReexportsSpec
+          Language.PureScript.Ide.SourceFileSpec
+          Language.PureScript.Ide.StateSpec
+          Language.PureScript.Ide.Test
+          PscIdeSpec
+          TestCompiler
+          TestDocs
+          TestPrimDocs
+          TestPsci
+          TestPsci.CommandTest
+          TestPsci.CompletionTest
+          TestPsci.EvalTest
+          TestPsci.TestEnv
+          TestPscIde
+          TestPscPublish
+          TestUtils
+    default-language: Haskell2010
+    hs-source-dirs:
+          tests
diff --git a/src/Language/PureScript/Constants.hs b/src/Language/PureScript/Constants.hs
--- a/src/Language/PureScript/Constants.hs
+++ b/src/Language/PureScript/Constants.hs
@@ -384,6 +384,9 @@
 pattern Union :: Qualified (ProperName 'ClassName)
 pattern Union = Qualified (Just Prim) (ProperName "Union")
 
+pattern RowCons :: Qualified (ProperName 'ClassName)
+pattern RowCons = Qualified (Just Prim) (ProperName "RowCons")
+
 typ :: forall a. (IsString a) => a
 typ = "Type"
 
diff --git a/src/Language/PureScript/Docs/Prim.hs b/src/Language/PureScript/Docs/Prim.hs
--- a/src/Language/PureScript/Docs/Prim.hs
+++ b/src/Language/PureScript/Docs/Prim.hs
@@ -26,6 +26,7 @@
       , fail
       , warn
       , union
+      , rowCons
       , typeConcat
       , typeString
       , kindType
@@ -235,6 +236,13 @@
   , "(left-biased, including duplicates)."
   , ""
   , "The third type argument represents the union of the first two."
+  ]
+
+rowCons :: Declaration
+rowCons = primClass "RowCons" $ T.unlines
+  [ "The RowCons type class is a 4-way relation which asserts that one row of"
+  , "types can be obtained from another by inserting a new label/type pair on"
+  , "the left."
   ]
 
 typeConcat :: Declaration
diff --git a/src/Language/PureScript/Environment.hs b/src/Language/PureScript/Environment.hs
--- a/src/Language/PureScript/Environment.hs
+++ b/src/Language/PureScript/Environment.hs
@@ -327,6 +327,7 @@
     , (primName "Boolean",    (kindType, ExternData))
     , (primName "Partial",    (kindType, ExternData))
     , (primName "Union",      (FunKind (Row kindType) (FunKind (Row kindType) (FunKind (Row kindType) kindType)), ExternData))
+    , (primName "RowCons",    (FunKind kindSymbol (FunKind kindType (FunKind (Row kindType) (FunKind (Row kindType) kindType))), ExternData))
     , (primName "Fail",       (FunKind kindSymbol kindType, ExternData))
     , (primName "Warn",       (FunKind kindSymbol kindType, ExternData))
     , (primName "TypeString", (FunKind kindType kindSymbol, ExternData))
@@ -354,6 +355,16 @@
                              [ FunctionalDependency [0, 1] [2]
                              , FunctionalDependency [1, 2] [0]
                              , FunctionalDependency [2, 0] [1]
+                             ]))
+    -- class RowCons (l :: Symbol) (a :: Type) (i :: # Type) (o :: # Type) | l i a -> o, l o -> a i
+    , (primName "RowCons", (makeTypeClassData
+                             [ ("l", Just kindSymbol)
+                             , ("a", Just (Row kindType))
+                             , ("i", Just kindType)
+                             , ("o", Just kindType)
+                             ] [] []
+                             [ FunctionalDependency [0, 1, 2] [3]
+                             , FunctionalDependency [0, 3] [1, 2]
                              ]))
     ]
 
diff --git a/src/Language/PureScript/Ide/Externs.hs b/src/Language/PureScript/Ide/Externs.hs
--- a/src/Language/PureScript/Ide/Externs.hs
+++ b/src/Language/PureScript/Ide/Externs.hs
@@ -17,16 +17,14 @@
 module Language.PureScript.Ide.Externs
   ( readExternFile
   , convertExterns
-  , annotateModule
   ) where
 
-import           Protolude
+import           Protolude hiding (to, from, (&))
 
-import           Control.Lens ((^.))
+import           Control.Lens
 import           "monad-logger" Control.Monad.Logger
 import           Data.Aeson (decodeStrict)
 import qualified Data.ByteString as BS
-import qualified Data.Map as Map
 import           Data.Version (showVersion)
 import           Language.PureScript.Ide.Error (IdeError (..))
 import           Language.PureScript.Ide.Types
@@ -60,45 +58,76 @@
   where
     decls = map
       (IdeDeclarationAnn emptyAnn)
-      (cleanDeclarations ++ operatorDecls ++ tyOperatorDecls)
+      (resolvedDeclarations ++ operatorDecls ++ tyOperatorDecls)
     exportDecls = mapMaybe (convertExport . unwrapPositionedRef) (P.efExports ef)
     operatorDecls = convertOperator <$> P.efFixities ef
     tyOperatorDecls = convertTypeOperator <$> P.efTypeFixities ef
-    declarations = mapMaybe convertDecl (P.efDeclarations ef)
+    (toResolve, declarations) =
+      second catMaybes (partitionEithers (map convertDecl (P.efDeclarations ef)))
 
-    typeClassFilter = foldMap removeTypeDeclarationsForClass (filter isTypeClassDeclaration declarations)
-    cleanDeclarations = ordNub (appEndo typeClassFilter declarations)
+    -- It's important that we resolve synonyms first, because that resolving
+    -- process removes the corresponding type declarations. This way we don't
+    -- leave any stray type declarations for type classes around since they have
+    -- already been cleaned up in the type synonym pass.
+    resolver = resolveTypeClasses toResolve <> resolveSynonyms toResolve
+    resolvedDeclarations = appEndo resolver declarations
 
-removeTypeDeclarationsForClass :: IdeDeclaration -> Endo [IdeDeclaration]
-removeTypeDeclarationsForClass (IdeDeclTypeClass n) = Endo (filter notDuplicate)
-  where notDuplicate (IdeDeclType t) =
-          n ^. ideTCName . properNameT /= t ^. ideTypeName . properNameT
-        notDuplicate (IdeDeclTypeSynonym s) =
-          n ^. ideTCName . properNameT /= s ^. ideSynonymName . properNameT
-        notDuplicate _ = True
-removeTypeDeclarationsForClass _ = mempty
+resolveSynonyms :: [ToResolve] -> Endo [IdeDeclaration]
+resolveSynonyms = foldMap resolveSynonym
+  where
+    resolveSynonym tr = case tr of
+      TypeClassToResolve _ -> mempty
+      SynonymToResolve tn ty -> Endo $ \decls ->
+        case findType tn decls of
+          Nothing -> decls
+          Just tyDecl ->
+            IdeDeclTypeSynonym (IdeTypeSynonym tn ty (tyDecl^.ideTypeKind))
+            : filter (not . anyOf (_IdeDeclType.ideTypeName) (== tn)) decls
 
-isTypeClassDeclaration :: IdeDeclaration -> Bool
-isTypeClassDeclaration IdeDeclTypeClass{} = True
-isTypeClassDeclaration _ = False
+resolveTypeClasses :: [ToResolve] -> Endo [IdeDeclaration]
+resolveTypeClasses = foldMap resolveTypeClass
+  where
+    resolveTypeClass tr = case tr of
+      SynonymToResolve _ _ -> mempty
+      TypeClassToResolve tcn -> Endo $ \decls ->
+        case findSynonym (P.coerceProperName tcn) decls of
+          Nothing -> decls
+          Just tySyn -> IdeDeclTypeClass
+            (IdeTypeClass tcn (tySyn^.ideSynonymKind) [])
+            : filter (not . anyOf (_IdeDeclTypeSynonym.ideSynonymName) (== P.coerceProperName tcn)) decls
 
+findType :: P.ProperName 'P.TypeName -> [IdeDeclaration] -> Maybe IdeType
+findSynonym :: P.ProperName 'P.TypeName -> [IdeDeclaration] -> Maybe IdeTypeSynonym
+(findType, findSynonym) = ( findDecl _IdeDeclType ideTypeName
+                          , findDecl _IdeDeclTypeSynonym ideSynonymName
+                          )
+  where
+    findDecl p l tn decls = decls
+      & mapMaybe (preview p)
+      & find ((==) tn . view l)
+
+-- The Externs format splits information about synonyms across EDType and
+-- EDTypeSynonym declarations. For type classes there are three declarations
+-- involved. We collect these and resolve them at the end of the conversion process.
+data ToResolve
+  = TypeClassToResolve (P.ProperName 'P.ClassName)
+  | SynonymToResolve (P.ProperName 'P.TypeName) P.Type
+
 convertExport :: P.DeclarationRef -> Maybe (P.ModuleName, P.DeclarationRef)
 convertExport (P.ReExportRef m r) = Just (m, r)
 convertExport _ = Nothing
 
-convertDecl :: P.ExternsDeclaration -> Maybe IdeDeclaration
-convertDecl P.EDType{..} = Just $ IdeDeclType $
+convertDecl :: P.ExternsDeclaration -> Either ToResolve (Maybe IdeDeclaration)
+convertDecl P.EDType{..} = Right $ Just $ IdeDeclType $
   IdeType edTypeName edTypeKind
-convertDecl P.EDTypeSynonym{..} = Just $ IdeDeclTypeSynonym
-  (IdeTypeSynonym edTypeSynonymName edTypeSynonymType)
-convertDecl P.EDDataConstructor{..} = Just $ IdeDeclDataConstructor $
+convertDecl P.EDTypeSynonym{..} = Left (SynonymToResolve edTypeSynonymName edTypeSynonymType)
+convertDecl P.EDDataConstructor{..} = Right $ Just $ IdeDeclDataConstructor $
   IdeDataConstructor edDataCtorName edDataCtorTypeCtor edDataCtorType
-convertDecl P.EDValue{..} = Just $ IdeDeclValue $
+convertDecl P.EDValue{..} = Right $ Just $ IdeDeclValue $
   IdeValue edValueName edValueType
-convertDecl P.EDClass{..} = Just $ IdeDeclTypeClass $
-  IdeTypeClass edClassName []
-convertDecl P.EDKind{..} = Just (IdeDeclKind edKindName)
-convertDecl P.EDInstance{} = Nothing
+convertDecl P.EDClass{..} = Left (TypeClassToResolve edClassName)
+convertDecl P.EDKind{..} = Right (Just (IdeDeclKind edKindName))
+convertDecl P.EDInstance{} = Right Nothing
 
 convertOperator :: P.ExternsFixity -> IdeDeclaration
 convertOperator P.ExternsFixity{..} =
@@ -117,36 +146,3 @@
     efTypePrecedence
     efTypeAssociativity
     Nothing
-
-annotateModule
-  :: (DefinitionSites P.SourceSpan, TypeAnnotations)
-  -> [IdeDeclarationAnn]
-  -> [IdeDeclarationAnn]
-annotateModule (defs, types) decls =
-  map convertDeclaration decls
-  where
-    convertDeclaration :: IdeDeclarationAnn -> IdeDeclarationAnn
-    convertDeclaration (IdeDeclarationAnn ann d) = case d of
-      IdeDeclValue v ->
-        annotateFunction (v ^. ideValueIdent) (IdeDeclValue v)
-      IdeDeclType t ->
-        annotateType (t ^. ideTypeName . properNameT) (IdeDeclType t)
-      IdeDeclTypeSynonym s ->
-        annotateType (s ^. ideSynonymName . properNameT) (IdeDeclTypeSynonym s)
-      IdeDeclDataConstructor dtor ->
-        annotateValue (dtor ^. ideDtorName . properNameT) (IdeDeclDataConstructor dtor)
-      IdeDeclTypeClass tc ->
-        annotateType (tc ^. ideTCName . properNameT) (IdeDeclTypeClass tc)
-      IdeDeclValueOperator op ->
-        annotateValue (op ^. ideValueOpName . opNameT) (IdeDeclValueOperator op)
-      IdeDeclTypeOperator op ->
-        annotateType (op ^. ideTypeOpName . opNameT) (IdeDeclTypeOperator op)
-      IdeDeclKind i ->
-        annotateKind (i ^. properNameT) (IdeDeclKind i)
-      where
-        annotateFunction x = IdeDeclarationAnn (ann { _annLocation = Map.lookup (IdeNSValue (P.runIdent x)) defs
-                                                    , _annTypeAnnotation = Map.lookup x types
-                                                    })
-        annotateValue x = IdeDeclarationAnn (ann {_annLocation = Map.lookup (IdeNSValue x) defs})
-        annotateType x = IdeDeclarationAnn (ann {_annLocation = Map.lookup (IdeNSType x) defs})
-        annotateKind x = IdeDeclarationAnn (ann {_annLocation = Map.lookup (IdeNSKind x) defs})
diff --git a/src/Language/PureScript/Ide/State.hs b/src/Language/PureScript/Ide/State.hs
--- a/src/Language/PureScript/Ide/State.hs
+++ b/src/Language/PureScript/Ide/State.hs
@@ -139,7 +139,7 @@
                 ast =
                   fromMaybe (Map.empty, Map.empty) (Map.lookup moduleName asts)
                 cachedModule =
-                  annotateModule ast (fst (convertExterns ef))
+                  resolveLocationsForModule ast (fst (convertExterns ef))
                 tmp =
                   Map.insert moduleName cachedModule declarations
                 resolved =
@@ -222,7 +222,40 @@
   -> ModuleMap [IdeDeclarationAnn]
 resolveLocations asts =
   Map.mapWithKey (\mn decls ->
-                    maybe decls (flip annotateModule decls) (Map.lookup mn asts))
+                    maybe decls (flip resolveLocationsForModule decls) (Map.lookup mn asts))
+
+resolveLocationsForModule
+  :: (DefinitionSites P.SourceSpan, TypeAnnotations)
+  -> [IdeDeclarationAnn]
+  -> [IdeDeclarationAnn]
+resolveLocationsForModule (defs, types) decls =
+  map convertDeclaration decls
+  where
+    convertDeclaration :: IdeDeclarationAnn -> IdeDeclarationAnn
+    convertDeclaration (IdeDeclarationAnn ann d) = case d of
+      IdeDeclValue v ->
+        annotateFunction (v ^. ideValueIdent) (IdeDeclValue v)
+      IdeDeclType t ->
+        annotateType (t ^. ideTypeName . properNameT) (IdeDeclType t)
+      IdeDeclTypeSynonym s ->
+        annotateType (s ^. ideSynonymName . properNameT) (IdeDeclTypeSynonym s)
+      IdeDeclDataConstructor dtor ->
+        annotateValue (dtor ^. ideDtorName . properNameT) (IdeDeclDataConstructor dtor)
+      IdeDeclTypeClass tc ->
+        annotateType (tc ^. ideTCName . properNameT) (IdeDeclTypeClass tc)
+      IdeDeclValueOperator operator ->
+        annotateValue (operator ^. ideValueOpName . opNameT) (IdeDeclValueOperator operator)
+      IdeDeclTypeOperator operator ->
+        annotateType (operator ^. ideTypeOpName . opNameT) (IdeDeclTypeOperator operator)
+      IdeDeclKind i ->
+        annotateKind (i ^. properNameT) (IdeDeclKind i)
+      where
+        annotateFunction x = IdeDeclarationAnn (ann { _annLocation = Map.lookup (IdeNSValue (P.runIdent x)) defs
+                                                    , _annTypeAnnotation = Map.lookup x types
+                                                    })
+        annotateValue x = IdeDeclarationAnn (ann {_annLocation = Map.lookup (IdeNSValue x) defs})
+        annotateType x = IdeDeclarationAnn (ann {_annLocation = Map.lookup (IdeNSType x) defs})
+        annotateKind x = IdeDeclarationAnn (ann {_annLocation = Map.lookup (IdeNSKind x) defs})
 
 resolveInstances
   :: ModuleMap P.ExternsFile
diff --git a/src/Language/PureScript/Ide/Types.hs b/src/Language/PureScript/Ide/Types.hs
--- a/src/Language/PureScript/Ide/Types.hs
+++ b/src/Language/PureScript/Ide/Types.hs
@@ -53,6 +53,7 @@
 data IdeTypeSynonym = IdeTypeSynonym
   { _ideSynonymName :: P.ProperName 'P.TypeName
   , _ideSynonymType :: P.Type
+  , _ideSynonymKind :: P.Kind
   } deriving (Show, Eq, Ord)
 
 data IdeDataConstructor = IdeDataConstructor
@@ -63,6 +64,7 @@
 
 data IdeTypeClass = IdeTypeClass
   { _ideTCName :: P.ProperName 'P.ClassName
+  , _ideTCKind :: P.Kind
   , _ideTCInstances :: [IdeInstance]
   } deriving (Show, Eq, Ord)
 
diff --git a/src/Language/PureScript/Ide/Util.hs b/src/Language/PureScript/Ide/Util.hs
--- a/src/Language/PureScript/Ide/Util.hs
+++ b/src/Language/PureScript/Ide/Util.hs
@@ -74,7 +74,7 @@
       IdeDeclType t -> (t ^. ideTypeName . properNameT, t ^. ideTypeKind & P.prettyPrintKind)
       IdeDeclTypeSynonym s -> (s ^. ideSynonymName . properNameT, s ^. ideSynonymType & prettyPrintTypeSingleLine)
       IdeDeclDataConstructor d -> (d ^. ideDtorName . properNameT, d ^. ideDtorType & prettyPrintTypeSingleLine)
-      IdeDeclTypeClass d -> (d ^. ideTCName . properNameT, "type class")
+      IdeDeclTypeClass d -> (d ^. ideTCName . properNameT, d ^. ideTCKind & P.prettyPrintKind)
       IdeDeclValueOperator (IdeValueOperator op ref precedence associativity typeP) ->
         (P.runOpName op, maybe (showFixity precedence associativity (valueOperatorAliasT ref) op) prettyPrintTypeSingleLine typeP)
       IdeDeclTypeOperator (IdeTypeOperator op ref precedence associativity kind) ->
diff --git a/src/Language/PureScript/Interactive/IO.hs b/src/Language/PureScript/Interactive/IO.hs
--- a/src/Language/PureScript/Interactive/IO.hs
+++ b/src/Language/PureScript/Interactive/IO.hs
@@ -4,7 +4,9 @@
 
 import Control.Monad (msum)
 import Control.Monad.Trans.Maybe (MaybeT(..), runMaybeT)
-import System.Directory (createDirectoryIfMissing, getHomeDirectory, findExecutable)
+import System.Directory (XdgDirectory (..), createDirectoryIfMissing,
+                         getAppUserDataDirectory, getXdgDirectory,
+                         findExecutable, doesFileExist)
 import System.FilePath (takeDirectory, (</>))
 
 mkdirp :: FilePath -> IO ()
@@ -28,7 +30,12 @@
 --
 getHistoryFilename :: IO FilePath
 getHistoryFilename = do
-  home <- getHomeDirectory
-  let filename = home </> ".purescript" </> "psci_history"
-  mkdirp filename
-  return filename
+  appuserdata <- getAppUserDataDirectory "purescript"
+  olddirbool <- doesFileExist (appuserdata </> "psci_history")
+  if olddirbool
+      then return (appuserdata </> "psci_history")
+      else do
+        datadir <- getXdgDirectory XdgData "purescript"
+        let filename = datadir </> "psci_history"
+        mkdirp filename
+        return filename
diff --git a/src/Language/PureScript/Make.hs b/src/Language/PureScript/Make.hs
--- a/src/Language/PureScript/Make.hs
+++ b/src/Language/PureScript/Make.hs
@@ -144,12 +144,19 @@
   ((Module ss coms _ elaborated exps, env'), nextVar) <- runSupplyT 0 $ do
     [desugared] <- desugar externs [withPrim]
     runCheck' (emptyCheckState env) $ typeCheckModule desugared
-  regrouped <- createBindingGroups moduleName . collapseBindingGroups $ elaborated
+
+  -- desugar case declarations *after* type- and exhaustiveness checking
+  -- since pattern guards introduces cases which the exhaustiveness checker
+  -- reports as not-exhaustive.
+  (deguarded, nextVar') <- runSupplyT nextVar $ do
+    desugarCaseGuards elaborated
+
+  regrouped <- createBindingGroups moduleName . collapseBindingGroups $ deguarded
   let mod' = Module ss coms moduleName regrouped exps
       corefn = CF.moduleToCoreFn env' mod'
       [renamed] = renameInModules [corefn]
       exts = moduleToExternsFile mod' env'
-  evalSupplyT nextVar . codegen renamed env' . encode $ exts
+  evalSupplyT nextVar' . codegen renamed env' . encode $ exts
   return exts
 
 -- | Compiles in "make" mode, compiling each module separately to a @.js@ file and an @externs.json@ file.
diff --git a/src/Language/PureScript/Pretty/Values.hs b/src/Language/PureScript/Pretty/Values.hs
--- a/src/Language/PureScript/Pretty/Values.hs
+++ b/src/Language/PureScript/Pretty/Values.hs
@@ -141,16 +141,34 @@
   prettyPrintResult :: [GuardedExpr] -> Box
   prettyPrintResult [GuardedExpr [] v] = text " -> " <> prettyPrintValue (d - 1) v
   prettyPrintResult gs =
-    vcat left (map prettyPrintGuardedValue gs)
+    vcat left (map (prettyPrintGuardedValueSep (text " | ")) gs)
 
-  prettyPrintGuardedValue :: GuardedExpr -> Box
-  prettyPrintGuardedValue (GuardedExpr [ConditionGuard grd] val) = foldl1 before
-    [ text " | "
-    , prettyPrintValue (d - 1) grd
-    , text " -> "
+  prettyPrintGuardedValueSep :: Box -> GuardedExpr -> Box
+  prettyPrintGuardedValueSep _ (GuardedExpr [] val) =
+    text " -> " <> prettyPrintValue (d - 1) val
+
+  prettyPrintGuardedValueSep sep (GuardedExpr [guard] val) =
+    foldl1 before [ sep
+                  , prettyPrintGuard guard
+                  , prettyPrintGuardedValueSep sep (GuardedExpr [] val)
+                  ]
+
+  prettyPrintGuardedValueSep sep (GuardedExpr (guard : guards) val) =
+    vcat left [ foldl1 before
+                [ sep
+                , prettyPrintGuard guard
+                ]
+              , prettyPrintGuardedValueSep (text " , ") (GuardedExpr guards val)
+              ]
+
+  prettyPrintGuard (ConditionGuard cond) =
+    prettyPrintValue (d - 1) cond
+  prettyPrintGuard (PatternGuard binder val) =
+    foldl1 before
+    [ text (T.unpack (prettyPrintBinder binder))
+    , text " <- "
     , prettyPrintValue (d - 1) val
     ]
-  prettyPrintGuardedValue _ = internalError "There should only be ConditionGuards after desugaring cases"
 
 prettyPrintDoNotationElement :: Int -> DoNotationElement -> Box
 prettyPrintDoNotationElement d _ | d < 0 = ellipsis
diff --git a/src/Language/PureScript/Sugar/CaseDeclarations.hs b/src/Language/PureScript/Sugar/CaseDeclarations.hs
--- a/src/Language/PureScript/Sugar/CaseDeclarations.hs
+++ b/src/Language/PureScript/Sugar/CaseDeclarations.hs
@@ -5,6 +5,7 @@
 module Language.PureScript.Sugar.CaseDeclarations
   ( desugarCases
   , desugarCasesModule
+  , desugarCaseGuards
   ) where
 
 import Prelude.Compat
@@ -37,14 +38,23 @@
       <$> (desugarCases <=< desugarAbs <=< validateCases $ ds)
       <*> pure exps
 
+desugarCaseGuards
+  :: forall m. (MonadSupply m, MonadError MultipleErrors m)
+  => [Declaration]
+  -> m [Declaration]
+desugarCaseGuards declarations = parU declarations f
+  where
+    (f, _, _) = everywhereOnValuesM return desugarGuardedExprs return
+
 -- |
 -- Desugar case with pattern guards and pattern clauses to a
 -- series of nested case expressions.
 --
-desugarCase :: forall m. (MonadSupply m)
-            => Expr
-            -> m Expr
-desugarCase (Case scrut alternatives)
+desugarGuardedExprs
+  :: forall m. (MonadSupply m)
+  => Expr
+  -> m Expr
+desugarGuardedExprs (Case scrut alternatives)
   | any (not . isTrivialExpr) scrut = do
     -- in case the scrutinee is non trivial (e.g. not a Var or Literal)
     -- we may evaluate the scrutinee more than once when a guard occurrs.
@@ -55,16 +65,17 @@
            , ValueDeclaration scrut_id Private [] [MkUnguarded e]
            )
       )
-    Let scrut_decls <$> desugarCase (Case scrut' alternatives)
+    Let scrut_decls <$> desugarGuardedExprs (Case scrut' alternatives)
   where
     isTrivialExpr (Var _) = True
     isTrivialExpr (Literal _) = True
     isTrivialExpr (Accessor _ e) = isTrivialExpr e
     isTrivialExpr (Parens e) = isTrivialExpr e
     isTrivialExpr (PositionedValue _ _ e) = isTrivialExpr e
+    isTrivialExpr (TypedValue _ e _) = isTrivialExpr e
     isTrivialExpr _ = False
 
-desugarCase (Case scrut alternatives) =
+desugarGuardedExprs (Case scrut alternatives) =
   let
     -- Alternatives which do not have guards are
     -- left as-is. Alternatives which
@@ -206,8 +217,9 @@
     desugarAltOutOfLine alt_binder rem_guarded rem_alts mk_body
       | Just rem_case <- mkCaseOfRemainingGuardsAndAlts = do
 
-        desugared   <- desugarCase rem_case
-        rem_case_id <- freshIdent'
+        desugared     <- desugarGuardedExprs rem_case
+        rem_case_id   <- freshIdent'
+        unused_binder <- freshIdent'
 
         let
           goto_rem_case :: Expr
@@ -216,8 +228,8 @@
           alt_fail = [CaseAlternative [NullBinder] [MkUnguarded goto_rem_case]]
 
         pure $ Let [
-            ValueDeclaration rem_case_id Private [NullBinder]
-              [MkUnguarded desugared]
+          ValueDeclaration rem_case_id Private []
+            [MkUnguarded (Abs (VarBinder unused_binder) desugared)]
           ] (mk_body alt_fail)
 
       | otherwise
@@ -251,8 +263,14 @@
     alts' <- desugarAlternatives alternatives
     return $ optimize (Case scrut alts')
 
-desugarCase v = pure v
+desugarGuardedExprs (TypedValue infered e ty) =
+  TypedValue infered <$> desugarGuardedExprs e <*> pure ty
 
+desugarGuardedExprs (PositionedValue ss comms e) =
+  PositionedValue ss comms <$> desugarGuardedExprs e
+
+desugarGuardedExprs v = pure v
+
 -- |
 -- Validates that case head and binder lengths match.
 --
@@ -262,12 +280,12 @@
   (f, _, _) = everywhereOnValuesM return validate return
 
   validate :: Expr -> m Expr
-  validate (Case vs alts) = do
+  validate c@(Case vs alts) = do
     let l = length vs
         alts' = filter ((l /=) . length . caseAlternativeBinders) alts
     unless (null alts') $
       throwError . MultipleErrors $ fmap (altError l) (caseAlternativeBinders <$> alts')
-    desugarCase (Case vs alts)
+    return c
   validate other = return other
 
   altError :: Int -> [Binder] -> ErrorMessage
@@ -370,8 +388,7 @@
             else replicateM (length argNames) freshIdent'
   let vars = map (Var . Qualified Nothing) args
       binders = [ CaseAlternative bs result | (bs, result) <- alternatives ]
-  case_ <- desugarCase (Case vars binders)
-  let value = foldr (Abs . VarBinder) case_ args
+  let value = foldr (Abs . VarBinder) (Case vars binders) args
 
   return $ ValueDeclaration ident Public [] [MkUnguarded value]
   where
diff --git a/src/Language/PureScript/TypeChecker/Entailment.hs b/src/Language/PureScript/TypeChecker/Entailment.hs
--- a/src/Language/PureScript/TypeChecker/Entailment.hs
+++ b/src/Language/PureScript/TypeChecker/Entailment.hs
@@ -55,7 +55,9 @@
   | AppendSymbolInstance
   -- ^ Computed instance of AppendSymbol
   | UnionInstance
-  -- ^ Computed instance of RowUnion
+  -- ^ Computed instance of Union
+  | ConsInstance
+  -- ^ Computed instance of RowCons
   deriving (Show, Eq)
 
 -- | Extract the identifier of a named instance
@@ -167,6 +169,8 @@
     forClassName _ C.Union [l, r, u]
       | Just (lOut, rOut, uOut, cst) <- unionRows l r u
       = [ TypeClassDictionaryInScope UnionInstance [] C.Union [lOut, rOut, uOut] cst ]
+    forClassName _ C.RowCons [TypeLevelString sym, ty, r, _]
+      = [ TypeClassDictionaryInScope ConsInstance [] C.RowCons [TypeLevelString sym, ty, r, RCons (Label sym) ty r] Nothing ]
     forClassName ctx cn@(Qualified (Just mn) _) tys = concatMap (findDicts ctx cn) (ordNub (Nothing : Just mn : map Just (mapMaybe ctorModules tys)))
     forClassName _ _ _ = internalError "forClassName: expected qualified class name"
 
@@ -326,6 +330,7 @@
               -- We need the subgoal dictionary to appear in the term somewhere
               return $ App (Abs (VarBinder (Ident C.__unused)) valUndefined) e
             mkDictionary UnionInstance _ = return valUndefined
+            mkDictionary ConsInstance _ = return valUndefined
             mkDictionary (WarnInstance msg) _ = do
               tell . errorMessage $ UserDefinedWarning msg
               -- We cannot call the type class constructor here because Warn is declared in Prim.
diff --git a/src/Language/PureScript/TypeChecker/Types.hs b/src/Language/PureScript/TypeChecker/Types.hs
--- a/src/Language/PureScript/TypeChecker/Types.hs
+++ b/src/Language/PureScript/TypeChecker/Types.hs
@@ -556,12 +556,7 @@
     let ns = concatMap binderNames binders in length (ordNub ns) == length ns
   m1 <- M.unions <$> zipWithM inferBinder nvals binders
   r <- bindLocalVariables [ (name, ty, Defined) | (name, ty) <- M.toList m1 ] $
-    CaseAlternative binders <$>
-      case result of
-        [MkUnguarded val] -> do
-          val' <- TypedValue True <$> check val ret <*> pure ret
-          return [MkUnguarded val']
-        gs -> forM gs (\ge -> checkGuardedRhs ge ret)
+       CaseAlternative binders <$> forM result (\ge -> checkGuardedRhs ge ret)
   rs <- checkBinders nvals ret bs
   return $ r : rs
 
@@ -573,12 +568,18 @@
 checkGuardedRhs (GuardedExpr [] rhs) ret = do
   rhs' <- TypedValue True <$> check rhs ret <*> pure ret
   return $ GuardedExpr [] rhs'
-checkGuardedRhs (GuardedExpr [ConditionGuard cond] rhs) ret = do
+checkGuardedRhs (GuardedExpr (ConditionGuard cond : guards) rhs) ret = do
   cond' <- withErrorMessageHint ErrorCheckingGuard $ check cond tyBoolean
-  rhs' <- TypedValue True <$> check rhs ret <*> pure ret
-  return $ GuardedExpr [ConditionGuard cond'] rhs'
-checkGuardedRhs _ _ =
-  internalError "Pattern not desugared"
+  GuardedExpr guards' rhs' <- checkGuardedRhs (GuardedExpr guards rhs) ret
+  return $ GuardedExpr (ConditionGuard cond' : guards') rhs'
+checkGuardedRhs (GuardedExpr (PatternGuard binder expr : guards) rhs) ret = do
+  expr'@(TypedValue _ _ ty) <- infer expr
+  variables <- inferBinder ty binder
+  GuardedExpr guards' rhs' <- bindLocalVariables [ (name, bty, Defined)
+                                                 | (name, bty) <- M.toList variables
+                                                 ] $
+    checkGuardedRhs (GuardedExpr guards rhs) ret
+  return $ GuardedExpr (PatternGuard binder expr' : guards') rhs'
 
 -- |
 -- Check the type of a value, rethrowing errors to provide a better error message
diff --git a/tests/Language/PureScript/Ide/ImportsSpec.hs b/tests/Language/PureScript/Ide/ImportsSpec.hs
--- a/tests/Language/PureScript/Ide/ImportsSpec.hs
+++ b/tests/Language/PureScript/Ide/ImportsSpec.hs
@@ -56,9 +56,6 @@
 consoleImport = testParseImport "import Control.Monad.Eff.Console (log) as Console"
 maybeImport = testParseImport "import Data.Maybe (Maybe(Just))"
 
-wildcard :: P.Type
-wildcard = P.TypeWildcard $ P.SourceSpan "" (P.SourcePos 0 0) (P.SourcePos 0 0)
-
 spec :: Spec
 spec = do
   describe "determining the importsection" $ do
@@ -104,13 +101,13 @@
   describe "import commands" $ do
     let simpleFileImports = let (_, _, i, _) = splitSimpleFile in i
         addValueImport i mn is =
-          prettyPrintImportSection (addExplicitImport' (IdeDeclValue (IdeValue (P.Ident i) wildcard)) mn is)
+          prettyPrintImportSection (addExplicitImport' (_idaDeclaration (Test.ideValue i Nothing)) mn is)
         addOpImport op mn is =
-          prettyPrintImportSection (addExplicitImport' (IdeDeclValueOperator (IdeValueOperator op (P.Qualified Nothing (Left (P.Ident ""))) 2 P.Infix Nothing)) mn is)
+          prettyPrintImportSection (addExplicitImport' (_idaDeclaration (Test.ideValueOp op (P.Qualified Nothing (Left "")) 2 Nothing Nothing)) mn is)
         addDtorImport i t mn is =
-          prettyPrintImportSection (addExplicitImport' (IdeDeclDataConstructor (IdeDataConstructor (P.ProperName i) t wildcard)) mn is)
+          prettyPrintImportSection (addExplicitImport' (_idaDeclaration (Test.ideDtor i t Nothing)) mn is)
         addTypeImport i mn is =
-          prettyPrintImportSection (addExplicitImport' (IdeDeclType (IdeType (P.ProperName i) P.kindType)) mn is)
+          prettyPrintImportSection (addExplicitImport' (_idaDeclaration (Test.ideType i Nothing)) mn is)
     it "adds an implicit unqualified import to a file without any imports" $
       shouldBe
         (addImplicitImport' [] (P.moduleNameFromString "Data.Map"))
@@ -144,7 +141,7 @@
         ]
     it "adds an operator to an explicit import list" $
       shouldBe
-        (addOpImport (P.OpName "<~>") (P.moduleNameFromString "Data.Array") explicitImports)
+        (addOpImport "<~>" (P.moduleNameFromString "Data.Array") explicitImports)
         [ "import Prelude"
         , "import Data.Array (tail, (<~>))"
         ]
@@ -156,21 +153,21 @@
           ]
     it "adds the type for a given DataConstructor" $
         shouldBe
-          (addDtorImport "Just" (P.ProperName "Maybe") (P.moduleNameFromString "Data.Maybe") simpleFileImports)
+          (addDtorImport "Just" "Maybe" (P.moduleNameFromString "Data.Maybe") simpleFileImports)
           [ "import Prelude"
           , "import Data.Maybe (Maybe(..))"
           ]
     it "adds a dataconstructor to an existing type import" $ do
       let Right (_, _, typeImports, _) = sliceImportSection (withImports ["import Data.Maybe (Maybe)"])
       shouldBe
-        (addDtorImport "Just" (P.ProperName "Maybe") (P.moduleNameFromString "Data.Maybe") typeImports)
+        (addDtorImport "Just" "Maybe" (P.moduleNameFromString "Data.Maybe") typeImports)
         [ "import Prelude"
         , "import Data.Maybe (Maybe(..))"
         ]
     it "doesn't add a dataconstructor to an existing type import with open dtors" $ do
       let Right (_, _, typeImports, _) = sliceImportSection (withImports ["import Data.Maybe (Maybe(..))"])
       shouldBe
-        (addDtorImport "Just" (P.ProperName "Maybe") (P.moduleNameFromString "Data.Maybe") typeImports)
+        (addDtorImport "Just" "Maybe" (P.moduleNameFromString "Data.Maybe") typeImports)
         [ "import Prelude"
         , "import Data.Maybe (Maybe(..))"
         ]
@@ -186,10 +183,10 @@
     let Right (_, _, baseImports, _) = sliceImportSection $ withImports ["import Control.Monad (ap)"]
         moduleName = (P.moduleNameFromString "Control.Monad")
         addImport imports import' = addExplicitImport' import' moduleName imports
-        valueImport ident = (IdeDeclValue (IdeValue (P.Ident ident) wildcard))
-        typeImport name = (IdeDeclType (IdeType (P.ProperName name) P.kindType))
-        classImport name = (IdeDeclTypeClass (IdeTypeClass (P.ProperName name) []))
-        dtorImport name typeName = (IdeDeclDataConstructor (IdeDataConstructor (P.ProperName name) (P.ProperName typeName) wildcard))
+        valueImport ident = _idaDeclaration (Test.ideValue ident Nothing)
+        typeImport name = _idaDeclaration (Test.ideType name Nothing)
+        classImport name = _idaDeclaration (Test.ideTypeClass name P.kindType [])
+        dtorImport name typeName = _idaDeclaration (Test.ideDtor name typeName Nothing)
         -- expect any list of provided identifiers, when imported, to come out as specified
         expectSorted imports expected = shouldBe
           (ordNub $ map
diff --git a/tests/Language/PureScript/Ide/ReexportsSpec.hs b/tests/Language/PureScript/Ide/ReexportsSpec.hs
--- a/tests/Language/PureScript/Ide/ReexportsSpec.hs
+++ b/tests/Language/PureScript/Ide/ReexportsSpec.hs
@@ -7,49 +7,39 @@
 import qualified Data.Map as Map
 import           Language.PureScript.Ide.Reexports
 import           Language.PureScript.Ide.Types
+import           Language.PureScript.Ide.Test
 import qualified Language.PureScript as P
 import           Test.Hspec
 
-type Module = (P.ModuleName, [IdeDeclarationAnn])
-
-m :: Text -> P.ModuleName
-m = P.moduleNameFromString
-
-d :: IdeDeclaration -> IdeDeclarationAnn
-d = IdeDeclarationAnn emptyAnn
-
-exportedFrom :: Text -> IdeDeclarationAnn -> IdeDeclarationAnn
-exportedFrom mn (IdeDeclarationAnn ann decl) = IdeDeclarationAnn (ann {_annExportedFrom = Just (m mn)}) decl
-
 valueA, typeA, classA, dtorA1, dtorA2 :: IdeDeclarationAnn
-valueA = d (IdeDeclValue (IdeValue (P.Ident "valueA") P.REmpty))
-typeA = d (IdeDeclType (IdeType(P.ProperName "TypeA") P.kindType))
-classA = d (IdeDeclTypeClass (IdeTypeClass (P.ProperName "ClassA") []))
-dtorA1 = d (IdeDeclDataConstructor (IdeDataConstructor (P.ProperName "DtorA1") (P.ProperName "TypeA") P.REmpty))
-dtorA2 = d (IdeDeclDataConstructor (IdeDataConstructor (P.ProperName "DtorA2") (P.ProperName "TypeA") P.REmpty))
+valueA = ideValue "valueA" Nothing
+typeA = ideType "TypeA" Nothing
+classA = ideTypeClass "ClassA" P.kindType []
+dtorA1 = ideDtor "DtorA1" "TypeA" Nothing
+dtorA2 = ideDtor "DtorA2" "TypeA" Nothing
 
 env :: ModuleMap [IdeDeclarationAnn]
 env = Map.fromList
-  [ (m "A", [valueA, typeA, classA, dtorA1, dtorA2])
+  [ (mn "A", [valueA, typeA, classA, dtorA1, dtorA2])
   ]
 
 type Refs = [(P.ModuleName, P.DeclarationRef)]
 
 succTestCases :: [(Text, Refs, [IdeDeclarationAnn])]
 succTestCases =
-  [ ("resolves a value reexport", [(m "A", P.ValueRef (P.Ident "valueA"))], [exportedFrom "A" valueA])
+  [ ("resolves a value reexport", [(mn "A", P.ValueRef (P.Ident "valueA"))], [valueA `annExp` "A"])
   , ("resolves a type reexport with explicit data constructors"
-    , [(m "A", P.TypeRef (P.ProperName "TypeA") (Just [P.ProperName "DtorA1"]))], [exportedFrom "A" typeA, exportedFrom "A" dtorA1])
+    , [(mn "A", P.TypeRef (P.ProperName "TypeA") (Just [P.ProperName "DtorA1"]))], [typeA `annExp` "A", dtorA1 `annExp` "A"])
   , ("resolves a type reexport with implicit data constructors"
-    , [(m "A", P.TypeRef (P.ProperName "TypeA") Nothing)], map (exportedFrom "A") [typeA, dtorA1, dtorA2])
-  , ("resolves a class reexport", [(m "A", P.TypeClassRef (P.ProperName "ClassA"))], [exportedFrom "A" classA])
+    , [(mn "A", P.TypeRef (P.ProperName "TypeA") Nothing)], map (`annExp` "A") [typeA, dtorA1, dtorA2])
+  , ("resolves a class reexport", [(mn "A", P.TypeClassRef (P.ProperName "ClassA"))], [classA `annExp` "A"])
   ]
 
 failTestCases :: [(Text, Refs)]
 failTestCases =
-  [ ("fails to resolve a non existing value", [(m "A", P.ValueRef (P.Ident "valueB"))])
-  , ("fails to resolve a non existing type reexport" , [(m "A", P.TypeRef (P.ProperName "TypeB") Nothing)])
-  , ("fails to resolve a non existing class reexport", [(m "A", P.TypeClassRef (P.ProperName "ClassB"))])
+  [ ("fails to resolve a non existing value", [(mn "A", P.ValueRef (P.Ident "valueB"))])
+  , ("fails to resolve a non existing type reexport" , [(mn "A", P.TypeRef (P.ProperName "TypeB") Nothing)])
+  , ("fails to resolve a non existing class reexport", [(mn "A", P.TypeClassRef (P.ProperName "ClassB"))])
   ]
 
 spec :: Spec
diff --git a/tests/Language/PureScript/Ide/SourceFileSpec.hs b/tests/Language/PureScript/Ide/SourceFileSpec.hs
--- a/tests/Language/PureScript/Ide/SourceFileSpec.hs
+++ b/tests/Language/PureScript/Ide/SourceFileSpec.hs
@@ -97,12 +97,12 @@
     ideState = emptyIdeState `s3`
       [ ("Test",
          [ ideValue "sfValue" Nothing `annLoc` valueSS
-         , ideSynonym "SFType" P.tyString `annLoc` synonymSS
+         , ideSynonym "SFType" P.tyString P.kindType `annLoc` synonymSS
          , ideType "SFData" Nothing `annLoc` typeSS
          , ideDtor "SFOne" "SFData" Nothing `annLoc` typeSS
          , ideDtor "SFTwo" "SFData" Nothing `annLoc` typeSS
          , ideDtor "SFThree" "SFData" Nothing `annLoc` typeSS
-         , ideTypeClass "SFClass" [] `annLoc` classSS
+         , ideTypeClass "SFClass" P.kindType [] `annLoc` classSS
          , ideValueOp "<$>" (P.Qualified Nothing (Left "")) 0 Nothing Nothing
            `annLoc` valueOpSS
          , ideTypeOp "~>" (P.Qualified Nothing "") 0 Nothing Nothing
diff --git a/tests/Language/PureScript/Ide/StateSpec.hs b/tests/Language/PureScript/Ide/StateSpec.hs
--- a/tests/Language/PureScript/Ide/StateSpec.hs
+++ b/tests/Language/PureScript/Ide/StateSpec.hs
@@ -6,6 +6,7 @@
 import           Control.Lens hiding ((&))
 import           Language.PureScript.Ide.Types
 import           Language.PureScript.Ide.State
+import           Language.PureScript.Ide.Test
 import qualified Language.PureScript as P
 import           Test.Hspec
 import qualified Data.Map as Map
@@ -34,9 +35,6 @@
 d :: IdeDeclaration -> IdeDeclarationAnn
 d = IdeDeclarationAnn emptyAnn
 
-mn :: Text -> P.ModuleName
-mn = P.moduleNameFromString
-
 testState :: ModuleMap [IdeDeclarationAnn]
 testState = Map.fromList [testModule]
 
@@ -72,7 +70,7 @@
  -- }
 
 moduleMap :: ModuleMap [IdeDeclarationAnn]
-moduleMap = Map.singleton (mn "ClassModule") [d (IdeDeclTypeClass (IdeTypeClass (P.ProperName "MyClass") []))]
+moduleMap = Map.singleton (mn "ClassModule") [ideTypeClass "MyClass" P.kindType []]
 
 ideInstance :: IdeInstance
 ideInstance = IdeInstance (mn "InstanceModule") (P.Ident "myClassInstance") mempty mempty
diff --git a/tests/Language/PureScript/Ide/Test.hs b/tests/Language/PureScript/Ide/Test.hs
--- a/tests/Language/PureScript/Ide/Test.hs
+++ b/tests/Language/PureScript/Ide/Test.hs
@@ -49,8 +49,8 @@
 annLoc :: IdeDeclarationAnn -> P.SourceSpan -> IdeDeclarationAnn
 annLoc (IdeDeclarationAnn a d) loc = IdeDeclarationAnn a {_annLocation = Just loc} d
 
-annExp :: IdeDeclarationAnn -> P.ModuleName -> IdeDeclarationAnn
-annExp (IdeDeclarationAnn a d) e = IdeDeclarationAnn a {_annExportedFrom = Just e} d
+annExp :: IdeDeclarationAnn -> Text -> IdeDeclarationAnn
+annExp (IdeDeclarationAnn a d) e = IdeDeclarationAnn a {_annExportedFrom = Just (mn e)} d
 
 annTyp :: IdeDeclarationAnn -> P.Type -> IdeDeclarationAnn
 annTyp (IdeDeclarationAnn a d) ta = IdeDeclarationAnn a {_annTypeAnnotation = Just ta} d
@@ -66,11 +66,11 @@
 ideType :: Text -> Maybe P.Kind -> IdeDeclarationAnn
 ideType pn ki = ida (IdeDeclType (IdeType (P.ProperName pn) (fromMaybe P.kindType ki)))
 
-ideSynonym :: Text -> P.Type -> IdeDeclarationAnn
-ideSynonym pn ty = ida (IdeDeclTypeSynonym (IdeTypeSynonym (P.ProperName pn) ty))
+ideSynonym :: Text -> P.Type -> P.Kind -> IdeDeclarationAnn
+ideSynonym pn ty kind = ida (IdeDeclTypeSynonym (IdeTypeSynonym (P.ProperName pn) ty kind))
 
-ideTypeClass :: Text -> [IdeInstance] -> IdeDeclarationAnn
-ideTypeClass pn instances = ida (IdeDeclTypeClass (IdeTypeClass (P.ProperName pn) instances))
+ideTypeClass :: Text -> P.Kind -> [IdeInstance] -> IdeDeclarationAnn
+ideTypeClass pn kind instances = ida (IdeDeclTypeClass (IdeTypeClass (P.ProperName pn) kind instances))
 
 ideDtor :: Text -> Text -> Maybe P.Type -> IdeDeclarationAnn
 ideDtor pn tn ty = ida (IdeDeclDataConstructor (IdeDataConstructor (P.ProperName pn) (P.ProperName tn) (fromMaybe P.tyString ty)))
diff --git a/tests/TestPsci.hs b/tests/TestPsci.hs
--- a/tests/TestPsci.hs
+++ b/tests/TestPsci.hs
@@ -1,22 +1,15 @@
-{-# LANGUAGE RecordWildCards #-}
-
 module TestPsci where
 
 import Prelude ()
 import Prelude.Compat
 
-import Control.Monad (when)
-import System.Exit (exitFailure)
-import Test.HUnit
+import Test.Hspec
 import TestPsci.CommandTest (commandTests)
 import TestPsci.CompletionTest (completionTests)
+import TestPsci.EvalTest (evalTests)
 
 main :: IO ()
-main = do
-  Counts{..} <- runTestTT allTests
-  when (errors + failures > 0) exitFailure
-
-allTests :: Test
-allTests = TestList [ completionTests
-                    , commandTests
-                    ]
+main = hspec $ do
+  completionTests
+  commandTests
+  evalTests
diff --git a/tests/TestPsci/CommandTest.hs b/tests/TestPsci/CommandTest.hs
--- a/tests/TestPsci/CommandTest.hs
+++ b/tests/TestPsci/CommandTest.hs
@@ -5,31 +5,30 @@
 
 import Control.Monad.Trans.RWS.Strict (get)
 import Language.PureScript.Interactive
-import Test.HUnit
+import Test.Hspec
 import TestPsci.TestEnv
 
-commandTests :: Test
-commandTests = TestLabel "commandTests" $ TestList $ map (TestCase . execTestPSCi)
-  [ do
-      run "import Prelude"
-      run "import Data.Functor"
-      run "import Control.Monad"
-      before <- psciImportedModules <$> get
-      length before `equalsTo` 3
-      run ":clear"
-      after <- psciImportedModules <$> get
-      length after `equalsTo` 0
-  , do
-      run "import Prelude"
-      run "import Data.Functor"
-      run "import Control.Monad"
-      before <- psciImportedModules <$> get
-      length before `equalsTo` 3
-      run ":reload"
-      after <- psciImportedModules <$> get
-      length after `equalsTo` 3
-  , do
-      run "import Prelude"
-      run "import Data.Array"
-      "let fac n = foldl mul 1 (1..n) in fac 10" `evaluatesTo` "3628800"
-  ]
+specPSCi :: String -> TestPSCi () -> Spec
+specPSCi label = specify label . execTestPSCi
+
+commandTests :: Spec
+commandTests = context "commandTests" $ do
+  specPSCi ":clear" $ do
+    run "import Prelude"
+    run "import Data.Functor"
+    run "import Control.Monad"
+    ms <- psciImportedModules <$> get
+    length ms `equalsTo` 3
+    run ":clear"
+    ms' <- psciImportedModules <$> get
+    length ms' `equalsTo` 0
+
+  specPSCi ":reload" $ do
+    run "import Prelude"
+    run "import Data.Functor"
+    run "import Control.Monad"
+    ms <- psciImportedModules <$> get
+    length ms `equalsTo` 3
+    run ":reload"
+    ms' <- psciImportedModules <$> get
+    length ms' `equalsTo` 3
diff --git a/tests/TestPsci/CompletionTest.hs b/tests/TestPsci/CompletionTest.hs
--- a/tests/TestPsci/CompletionTest.hs
+++ b/tests/TestPsci/CompletionTest.hs
@@ -3,8 +3,9 @@
 import Prelude ()
 import Prelude.Compat
 
-import Test.HUnit
+import Test.Hspec
 
+import           Control.Monad (mapM_)
 import           Control.Monad.Trans.State.Strict (evalStateT)
 import           Data.List (sort)
 import qualified Data.Text as T
@@ -14,10 +15,9 @@
 import           TestPsci.TestEnv (initTestPSCiEnv)
 import           TestUtils (supportModules)
 
-completionTests :: Test
-completionTests =
-  TestLabel "completionTests"
-    (TestList (map (TestCase . assertCompletedOk) completionTestData))
+completionTests :: Spec
+completionTests = context "completionTests" $
+  mapM_ assertCompletedOk completionTestData
 
 -- If the cursor is at the right end of the line, with the 1st element of the
 -- pair as the text in the line, then pressing tab should offer all the
@@ -84,12 +84,12 @@
   , ("Control.Monad.ST.new", ["Control.Monad.ST.newSTRef"])
   ]
 
-assertCompletedOk :: (String, [String]) -> Assertion
-assertCompletedOk (line, expecteds) = do
+assertCompletedOk :: (String, [String]) -> Spec
+assertCompletedOk (line, expecteds) = specify line $ do
   (unusedR, completions) <- runCM (completion' (reverse line, ""))
   let unused = reverse unusedR
   let actuals = map ((unused ++) . replacement) completions
-  sort expecteds @=? sort actuals
+  sort expecteds `shouldBe` sort actuals
 
 runCM :: CompletionM a -> IO a
 runCM act = do
diff --git a/tests/TestPsci/EvalTest.hs b/tests/TestPsci/EvalTest.hs
new file mode 100644
--- /dev/null
+++ b/tests/TestPsci/EvalTest.hs
@@ -0,0 +1,66 @@
+module TestPsci.EvalTest where
+
+import Prelude ()
+import Prelude.Compat
+
+import           Control.Monad (forM_, foldM_)
+import           Control.Monad.IO.Class (liftIO)
+import           Data.List (stripPrefix, intercalate)
+import           Data.List.Split (splitOn)
+import           System.Directory (getCurrentDirectory)
+import           System.Exit (exitFailure)
+import           System.FilePath ((</>), takeFileName)
+import qualified System.FilePath.Glob as Glob
+import           System.IO.UTF8 (readUTF8File)
+import           Test.Hspec
+import           TestPsci.TestEnv
+
+evalTests :: Spec
+evalTests = context "evalTests" $ do
+  testFiles <- runIO evalTestFiles
+  forM_ testFiles evalTest
+
+evalTestFiles :: IO [FilePath]
+evalTestFiles = do
+  cwd <- getCurrentDirectory
+  let psciExamples = cwd </> "examples" </> "psci"
+  Glob.globDir1 (Glob.compile "**/*.purs") psciExamples
+
+data EvalLine = Line String
+              | Comment EvalContext
+              | Empty
+              | Invalid String
+              deriving (Show)
+
+data EvalContext = ShouldEvaluateTo String
+                 | Paste [String]
+                 | None
+                 deriving (Show)
+
+evalCommentPrefix :: String
+evalCommentPrefix = "-- @"
+
+parseEvalLine :: String -> EvalLine
+parseEvalLine "" = Empty
+parseEvalLine line =
+  case stripPrefix evalCommentPrefix line of
+    Just rest ->
+      case splitOn " " rest of
+        "shouldEvaluateTo" : args -> Comment (ShouldEvaluateTo $ intercalate " " args)
+        "paste" : [] -> Comment (Paste [])
+        _ -> Invalid line
+    Nothing -> Line line
+
+evalTest :: FilePath -> Spec
+evalTest f = specify (takeFileName f) $ do
+  evalLines <- map parseEvalLine . lines <$> readUTF8File f
+  execTestPSCi $ foldM_ handleLine None evalLines
+
+handleLine :: EvalContext -> EvalLine -> TestPSCi EvalContext
+handleLine ctx Empty = pure ctx
+handleLine None (Line stmt) = run stmt >> pure None
+handleLine None (Comment ctx) = pure ctx
+handleLine (ShouldEvaluateTo expected) (Line expr) = expr `evaluatesTo` expected >> pure None
+handleLine (Paste ls) (Line l) = pure . Paste $ ls ++ [l]
+handleLine (Paste ls) (Comment (Paste _)) = run (intercalate "\n" ls) >> pure None
+handleLine _ line = liftIO $ putStrLn ("unexpected: " ++ show line) >> exitFailure
diff --git a/tests/TestPsci/TestEnv.hs b/tests/TestPsci/TestEnv.hs
--- a/tests/TestPsci/TestEnv.hs
+++ b/tests/TestPsci/TestEnv.hs
@@ -12,7 +12,7 @@
 import           System.FilePath ((</>))
 import qualified System.FilePath.Glob as Glob
 import           System.Process (readProcessWithExitCode)
-import           Test.HUnit ((@?=))
+import           Test.Hspec (shouldBe)
 
 -- | A monad transformer for handle PSCi actions in tests
 type TestPSCi a = RWST PSCiConfig () PSCiState IO a
@@ -70,9 +70,9 @@
 run :: String -> TestPSCi ()
 run comm = runAndEval comm $ jsEval *> return ()
 
--- | A lifted evaluation of HUnit '@?=' for the TestPSCi
+-- | A lifted evaluation of Hspec 'shouldBe' for the TestPSCi
 equalsTo :: (Eq a, Show a) => a -> a -> TestPSCi ()
-equalsTo x y = liftIO $ x @?= y
+equalsTo x y = liftIO $ x `shouldBe` y
 
 -- | An assertion to check if a command evaluates to a string
 evaluatesTo :: String -> String -> TestPSCi ()
