I'm making some bindings to C from Haskell, and trying to make it safer with LiquidHaskell. I'm having some trouble with specifying the length of a bytestring in the LH type annotation.
I have an enhanced ByteString type in LiquidHaskell that includes its length:
{-@ type ByteString Blen = {v:B.ByteString | bslen v == Blen} @-}
I am getting the following error when I run Liquidhaskell:
**** RESULT: UNSAFE ************************************************************
/home/t/liquidproblem/Main.hs:47:3-22: Error: Liquid Type Mismatch
47 | Bi.PS foreignPtr 0 l
^^^^^^^^^^^^^^^^^^^^
Inferred type
VV : {v : Data.ByteString.Internal.ByteString | 0 <= bslen v
&& bslen v == stringlen v}
not a subtype of Required type
VV : {VV : Data.ByteString.Internal.ByteString | bslen VV == l}
In Context
l : {l : GHC.Types.Int | l >= 0}
Line 47 is:
44 {-@ makeBs :: ForeignPtr Word8 -> l:NonNeg -> ByteString l @-}
45 makeBs :: F.ForeignPtr F.Word8 -> Int -> B.ByteString
46 makeBs foreignPtr l =
47 Bi.PS foreignPtr 0 l
(I know this seems a bit of a silly function, but it got put in because the debugging process was to factor out bits and put LH annotations on them till I found the problem.)
The relevant imports are:
import qualified Data.ByteString.Internal as Bi
import qualified Data.ByteString as B
import qualified Foreign as F
The LH NonNeg type is
{-@ type NonNeg = {i:Int | i >= 0} @-}