ucsd-progsys / liquidhaskell

Liquid Types For Haskell

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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 } @-}
  |          ^^^^^^^^^^^^^^^^^^^^
  1. 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?