3

Why does this pass Liquid Haskell verification?

{-@ sub :: Nat -> Nat -> Int @-}                                                                                                         
sub :: Int -> Int -> Int 
sub i j = i - j 

Does it mean that Nat is the same as Int from LH's point of view?

jberryman
  • 16,334
  • 5
  • 42
  • 83
RandomB
  • 3,367
  • 19
  • 30
  • 2
    The documentation specifies that `[lq| type Nat = {v:Int | 0 <= v} |]`, so it is a *subset*. – Willem Van Onsem May 23 '19 at 14:17
  • 1
    Your annotation states that if you take the difference of two `Nat`s, the result is an `Int`, which looks correct. By contrast, `Nat -> Nat -> Nat` would fail. Hence, they are not the same. – chi May 23 '19 at 14:18
  • hm, makes sense, so why this snippet passes verification? What will happen if I call `sub` somewhere with `-1` as arguments? LH should fail? May be LH does not require to match the signature totally? – RandomB May 23 '19 at 14:19
  • @chi seems that `sub` in LH is "subset" of `sub` in Haskell (if we can say it)? And both functions signatures may be little bit different (I tried `Float` and LH detects error). – RandomB May 23 '19 at 14:21
  • @Paul-AG: that is because the "root type" is `Int`, as is specified by `v:Int`. – Willem Van Onsem May 23 '19 at 14:24
  • @WillemVanOnsem so it's not like `newtype` but like `type`? And another question: LH wants to match the type of result totally and fails if subrange of result does not match refinement type in contract. But it is satisfied just with _root type_ when it matches types of arguments? – RandomB May 23 '19 at 14:45
  • 1
    @Paul-AG It's not a totally different type (`newtype`) or a synonym for an existing type (`type`). It's a refinement type. That is, it's a value of the same type with a refinement - additional restrictions on the value. It type checks if Liquid Haskell can prove that all the refinements are valid. – Carl May 23 '19 at 15:52

1 Answers1

6

Suppose you say to me, "Hey, I'd like an apple!". I reply: "Sorry, I only have red apples.". You're going to look at me pretty funny, huh? A red apple is an apple!

If a function asks for an Int as an argument, it's no problem to hand it an Int that you know is not negative.

Daniel Wagner
  • 145,880
  • 9
  • 220
  • 380