For the sake of exploring libraries with complex types and typeclass instances, I want to check from the REPL whether a typeclass constraint is satisfied or not (provided all the relevant dataypes and instances are in scope).
For example: in rel8 1.5.0, is the constraint Table Expr (Expr Int, Expr Bool)
satisfied? (It's not, as Int
lacks a DBType
instance, so the preconditions fail).
Non-solutions:
Using :kind!
. This only checks that the constraint is well-formed, not that it's satisified.
ghci> :kind! (Table Expr (Expr Int, Expr Bool))
(Table Expr (Expr Int, Expr Bool)) :: Constraint
= Table Expr (Expr Int, Expr Bool)
Using :instances
. Doesn't seem to work with multi-parameter typeclasses like Table
, and moreover it returns all possible instances, which can be verbose.
ghci> :instances Expr
instance Reifiable Expr
instance Nullifiable Expr
instance GRecordable Expr
ghci> :instances (Expr Int, Expr Bool)
instance [safe] NotNull (Expr Int, Expr Bool)
instance [safe] Nullable (Expr Int, Expr Bool)
instance Show (Expr Int, Expr Bool)
instance GHC.Generics.Generic (Expr Int, Expr Bool)
I have defined the following function in my .ghci
file:
:set -XAllowAmbiguousTypes
:{
yep :: forall c . c => ()
yep = ()
:}
Which can be used like this
ghci> yep @(Table Expr (Expr Int, Expr Bool))
<interactive>:4:1: error: [GHC-39999]
• No instance for ‘DBType Int’ arising from a use of ‘yep’
• In the expression: yep @(Table Expr (Expr Int, Expr Bool))
In an equation for ‘it’:
it = yep @(Table Expr (Expr Int, Expr Bool))
ghci> yep @(Table Expr (Expr Int32, Expr Bool))
()