content: {-# LANGUAGE TypeInType, RankNTypes, GADTs, TypeOperators #-}
  
  -- Opposite of the 'shouldNotTypecheck' function from
  -- https://github.com/CRogers/should-not-typecheck
  --
  
  module TestUtils where
  
  import Control.DeepSeq (force, NFData (..))
  import Control.Exception (evaluate, try, TypeError (..))
  import Test.HUnit.Lang (Assertion, assertFailure)
  
  -- | Hetero-kinded propositional type equality.
  -- If the type (a :~: b) is inhabited by Refl, a and b must be equal
  data (a :: k1) :~: (b :: k2) where
    Refl :: a :~: a
  
  -- | Instance which makes
  instance NFData (a :~: b) where
      rnf Refl = ()
  
  -- | Takes one argument, an expression that should  typecheck.
  -- It will fail the test if the expression does not typecheck.
  -- Requires Deferred Type Errors to be enabled for the file it is called in.
  shouldTypecheck :: NFData a => (() ~ () => a) -> Assertion
  shouldTypecheck a = do
    result <- try (evaluate $ force a)
    case result of
      Right _ -> return ()
      Left (TypeError msg) -> assertFailure $ "Expected expression to compile but it did not compile: \n" ++ msg
  