我在阅读this时发现了这一点:
度量-为了使Haskell函数细化 类型,我们需要将它们提升到优化类型级别。
还有其他一些文件断言,在合同中使用这种功能需要措施。但是我尝试过:
z = z[~z['is_duplicate']]
这可行,但是{-@ len :: List a -> Nat @-}
len :: List a -> Int
len Nil = 0
len (x `Cons` xs) = 1 + len xs
{-@ mymap :: (a -> b) -> xs : List a -> { ys : List b | len xs == len ys } @-}
mymap :: (a -> b) -> List a -> List b
mymap _ Nil = Nil
mymap f (x `Cons` xs) = f x `Cons` mymap f xs
不是 measure 。那么什么是确切的措施以及何时需要?
另一个没有len
才能运行的示例:
measure
像我在许多文档中发现的那样使用{-@ measure ln @-}
ln :: [a] -> Int
ln [] = 0
ln (x:y) = 1 + ln y
{-@ conc :: xs : [a] -> ys : [a] -> {zs : [a] | ln zs == ln xs + ln ys} @-}
conc :: [a] -> [a] -> [a]
conc [] ys = ys
conc (x:xs) ys = x : (conc xs ys)
会导致错误{-@ measure length @-}
(即来自Cannot extract measure from haskell function
的错误)。
答案 0 :(得分:7)
度量只是LiquidHaskell在验证时可以运行的一项功能,可用于细化和终止检查。您可能已经知道这一点。
您的第一个示例“有效”的原因(我认为它是不完整的,但我可以告诉您要做什么)的原因是len
已被定义为度量in the LiquidHaskell prelude(从技术上讲)这是一个“类度量”,这意味着它是多态的,因此可以与[]
列表和您的自定义List
一起使用。假设您从先前的问题中为this answer添加了Nil
和Cons
的注释,则在len
的优化中使用的mymap
不是您的{ {1}},但前奏len
(已经是一种度量)。
在第二个示例中,len
是必需的,因为measure
是度量名称空间中的新符号,除非您将其创建,否则它不存在。