Skip to content

Custom TypeError should include "arising from" clause

When a class constraint cannot be solved, the "No instance" message includes "arising from..." to specify the source of the constraint. However, if a custom type error is used to change the message, there is no "arising from..." clause. In complicated cases where the expression is large, this clause is useful in pinpointing the source of the error, so it would be helpful to include it.

For example, consider the following module:

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE UndecidableInstances #-}

module CustomTypeError where

import GHC.TypeLits

class C a where
  (%) :: a -> a -> a

instance TypeError (Text "No, Int cannot be a C") => C Int

foo = 2 % 3 :: Int

bar = 'a' % 'b' :: Char

This results in the following output:

CustomTypeError.hs:13:7: error:
     No, Int cannot be a C
     In the expression: 2 % 3 :: Int
      In an equation for foo: foo = 2 % 3 :: Int
   |
13 | foo = 2 % 3 :: Int
   |       ^^^^^

CustomTypeError.hs:15:7: error:
     No instance for (C Char) arising from a use of %
     In the expression: 'a' % 'b' :: Char
      In an equation for bar: bar = 'a' % 'b' :: Char
   |
15 | bar = 'a' % 'b' :: Char
   |       ^^^^^^^^^
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information