Document writing specs that involve type equalities
facundominguez opened this issue · comments
I've tried providing a spec for function g
without success.
{-# LANGUAGE GADTs #-}
module Test where
g :: a ~ Int => a
g = 0
Defining
{-@ g :: a ~ Int => a @-}
produces a parser error.
Is there a way to give specs to functions that use type equalities?
Does it work to remove the stuff before => in the LH spec?
This is accepted
{-@ g :: a @-}
but it is a wrong spec.
Probably
{-@ g :: Int @-}
should be accepted instead. But LH complains that it doesn't match the Haskell type signature.
That could be interesting. Can you elaborate a bit more about what is the meaning of {-@ g :: a @-}? Is it not a polymorphic value?
I'm discovering that it accepts
{-@ g :: { v:a | v == 0 } @-}
If I use
{-@ g :: { v:a | v == True } @-}
the error message is more telling. It shows that the spec of g
is treated as if I had typed:
{-@ g :: a ~ Int => { v:a | v == True } @-}
Specifically, the error message says
test.hs:4:10: error:
• Illegal type specification for `Test.g`
Test.g :: forall a .
(~<[]> (TYPE ('GHC.Types.BoxedRep 'GHC.Types.Lifted)) a GHC.Types.Int) =>
{VV : a | VV == true}
Sort Error in Refinement: {VV : a##aDW | VV == true}
The sort bool is not numeric
because
Cannot unify int with bool in expression: VV == true
because
Invalid Relation VV == true with operand types a##aDW and bool
Just
•
|
4 | {-@ g :: { v:a | v == True } @-}
| ^^^^^^^^^^^^^^^^^^^^
- In general we only want to put stuff in the LH spec which are not in the GHC spec.
...
It’s not really “wrong” as such as LH fills in the constraints from the GHC signature…
I finally get this bit of wisdom. So the fat arrow in specs is only meant to introduce bounded refinements, right?