这是一个计算给定列表中数字平均值的简单函数。
{-@ type NonZero = {v:Int | v/=0 } @-}
{-@ divide :: Int -> NonZero -> Int @-}
divide :: Int -> Int -> Int
divide n d = div n d
{-@ measure nonEmpty :: [a] -> Bool @-}
nonEmpty [] = False
nonEmpty _ = True
{-@ size :: xs:[a] -> {v:Nat | nonEmpty xs => v>0 } @-}
size :: [a] -> Int
size [] = 0
size (_:xs) = 1 + size xs
{-@ type NEList a = {v:[a] | nonEmpty v} @-}
{-@ avg :: NEList Int -> Int @-}
avg xs = divide (sum xs) (size xs)
不幸的是,这段代码没有进行类型检查。
但是,如果我nonEmpty
在定义函数后声明为度量,则它可以工作:
{-@ type NonZero = {v:Int | v/=0 } @-}
{-@ divide :: Int -> NonZero -> Int @-}
divide :: Int -> Int -> Int
divide n d = div n d
{-@ nonEmpty :: [a] -> Bool @-}
nonEmpty [] = False
nonEmpty _ = True
{-@ measure nonEmpty @-}
{-@ size :: xs:[a] -> {v:Nat | nonEmpty xs => v>0 } @-}
size :: [a] -> Int
size [] = 0
size (_:xs) = 1 + size xs
{-@ type NEList a = {v:[a] | nonEmpty v} @-}
{-@ avg :: NEList Int -> Int @-}
avg xs = divide (sum xs) (size xs)
那么有人可以解释为什么会这样吗?