haskell - Liquid haskell 用 PS 创建一个新的字节串
问题描述
我正在从 Haskell 对 C 进行一些绑定,并尝试使用 LiquidHaskell 使其更安全。我在指定 LH 类型注释中的字节串长度时遇到了一些麻烦。
我在 LiquidHaskell 中有一个增强的 ByteString 类型,包括它的长度:
{-@ type ByteString Blen = {v:B.ByteString | bslen v == Blen} @-}
运行 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}
第 47 行是:
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
(我知道这似乎是一个愚蠢的功能,但它被放入是因为调试过程是为了分解位并将 LH 注释放在它们上,直到我发现问题为止。)
相关的进口是:
import qualified Data.ByteString.Internal as Bi
import qualified Data.ByteString as B
import qualified Foreign as F
LH NonNeg 类型是
{-@ type NonNeg = {i:Int | i >= 0} @-}
解决方案
LiquidHaskell 不知道ByteString
返回的makeBs
有 length l
,并且无法从可用的信息中证明这一点。
你知道它会,因为你知道PS
构造函数的第三个参数是长度。因此,此时您有两个(或可能一个)选项:
- 您可以尝试告诉 LH 您对
PS
构造函数的了解,并给它一个注释,例如{-@ Bi.PS :: _ -> _ -> l:NonNeg -> ByteString l @-}
. 我试过了,但效果不太好,因为 LH 的签名中有内部 GHC 类型PS
似乎不太擅长处理。YMMV。或者,您可以: - 忘记注释并使用:
PS
标记您自己的函数。当然,如果标有 的函数变得更大,这会变得更加冒险——尽管看起来很愚蠢,但如果你走这条路,你可能想保留。assume
{-@ assume makeBs :: ForeignPtr Word8 -> l:NonNeg -> ByteString l @-}
assume
makeBs
推荐阅读
- ios - 通过cordova问题将字符串转换为ios中的日期
- javascript - Webpack 插件使用 asm 更改内容
- visual-c++ - 如何将浮点数拆分为两个变量?(c++)
- php - 即使遵循迁移过程,我也无法从 laravel 向表中添加新列?
- assembly - 如何在 8 位环境中检测 0 减 -128 溢出?
- javascript - 如何从节点计划中获取列表?
- sql - 由于 sql server 2012 中的邮件服务器故障,DB Mail 无法向收件人发送邮件
- excel - 使用在行之间迭代的 if 语句进行电源查询
- python - 在 python pandas 中读取 csv 并使用 subString contains 函数
- python - 关于dict.fromkeys,来自文件名的键,文件内的值,使用正则表达式