我正在阅读这个链接的内容,其中发现了以下信息:
Measures -- 为了允许 Haskell 函数出现在精化类型中,我们需要将它们提升到精化类型级别。
还有其他文件声称要使用这样的函数在合同中需要 measures 。但是我尝试了一下:
{-@ 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
这样可以工作,但是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
(即从length
中无法提取度量)。
{-@ measure length :: Foldable t => t a -> Int @-}
。看起来LH默认不会看到它的签名.. - RandomB