title: How to get better error messages with type-families?
body: <p>I'm trying to build a statically-typed authorisation system and have the following working code-snippet:</p>
  
  <pre><code>{-# LANGUAGE DataKinds, ScopedTypeVariables, TypeFamilies #-}
  
  module Try where
  
  import Data.Singletons.TH
  
  data FeatureFlag = Feature1 | Feature2 deriving (Eq, Show)
  $(genSingletons [''FeatureFlag])
  
  type family Feature (f :: FeatureFlag) (fs :: [FeatureFlag]) where
    Feature f '[] = 'False
    Feature f (f:fs) = 'True
    Feature f (q:fs) = Feature f fs  
  
  
  lockedFeatureAction :: (MonadIO (m fs), Feature 'Feature1 fs ~ 'True) =&gt; m fs ()
  lockedFeatureaction = undefined
  
  checkFeatureFlagsAndRun :: forall (fs :: [FeatureFlag]) . (SingI fs) =&gt; Proxy fs -&gt; AppM fs () -&gt; IO ()
  checkFeatureFlagsAndRun = undefined
  </code></pre>
  
  <p>And this is how it gets used:</p>
  
  <pre><code>ghci&gt; checkFeatureFlagsAndRun (Proxy :: Proxy '[ 'Feature1]) lockedFeatureAction
  </code></pre>
  
  <p>All is good when the types and stars align. However, if the types don't align, the error message is a classic Sherlock Holmes "whodunnit":</p>
  
  <pre><code>ghci&gt; checkFeatureFlagsAndRun (Proxy :: Proxy '[ 'Feature2]) lockedFeatureAction
  
  &lt;interactive&gt;:462:32: error:
      • Couldn't match type ‘'False’ with ‘'True’
          arising from a use of ‘lockedFeatureAction’
      • In the second argument of ‘checkFeatureFlagsAndRun’, namely ‘lockedFeatureAction’
        In the expression: checkFeatureFlagsAndRun (Proxy :: Proxy '[ 'Feature2]) lockedFeatureAction
        In an equation for ‘it’: it = checkFeatureFlagsAndRun (Proxy :: Proxy '[ 'Feature2]) lockedFeatureAction
  </code></pre>
  
  <p>I tried searching and stumbled upon <a href="https://kcsongor.github.io/report-stuck-families/" rel="noreferrer">https://kcsongor.github.io/report-stuck-families/</a>, which talks of <a href="https://www.stackage.org/haddock/lts-12.1/base-4.11.1.0/Control-Exception.html#t:TypeError" rel="noreferrer"><code>TypeError</code></a> I tried using it like this, but it didn't work:</p>
  
  <pre><code>type family Feature (f :: FeatureFlag) (fs :: [FeatureFlag]) where
    Feature f '[] = TypeError "Could not satisfy FeatureFlag conditions"
    Feature f (f:fs) = 'True
    Feature f (q:fs) = Feature f fs
  
  --     • Expected kind ‘ghc-prim-0.5.2.0:GHC.Types.Symbol -&gt; Bool’,
  --         but ‘TypeError’ has kind ‘*’
  --     • In the type ‘TypeError "Could not satisfy FeatureFlag conditions"’
  --       In the type family declaration for ‘Feature’
  --    |
  -- 19 |   Feature f '[] = TypeError "Could not satisfy FeatureFlag conditions"
  --    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  </code></pre>
  
  <p>What is the correct way to use <code>TypeError</code>? Alternatively, is there any other way to get better error messages?</p>