我正在尝试从书中学习 Liquid Haskell 。为了测试我的理解,我想编写一个函数log2
,它接受 2^n 形式的输入并输出 n。
我有以下代码:
powers :: [Int]
powers = map (2^) [0..]
{-@ type Powers = {v:Nat | v elem powers } @-}
{-@ log2 :: Powers -> Nat @-}
log2 :: Int -> Int
log2 n
| n == 1 = 0
| otherwise = 1 + log2 (div n 2)
但是在执行此代码时会出现一些奇怪的错误,即“精化中的排序错误”。我无法理解并解决此错误。
任何帮助将非常感激。
编辑:来自 Liquid Haskell 书:
谓词要么是原子谓词,通过比较两个表达式获得,要么是谓词函数对参数列表的应用......
在 Liquid Haskell 逻辑语法中,允许的谓词之一是:e r e
wherer
是原子二元关系(而函数只是一种特殊的关系)。
此外,在本教程中,他们将Even
子类型定义为:
{-@ type Even = {v:Int | v mod 2 == 0 } @-}
基于此,我认为elem
应该工作。
但现在正如@ThomasM.DuBuisson 指出的那样,我想改写自己的elem'
,以避免混淆。
elem' :: Int -> [Int] -> Bool
elem' _ [] = False
elem' e (x:xs)
| e==x = True
| otherwise = elem' e xs
现在,据我了解,为了能够将其elem'
用作谓词函数,我需要将其提升为度量。所以我添加了以下内容:
{-@ measure elem' :: Int -> [Int] -> Bool @-}
现在我在类型定义中替换elem
为. 但我仍然得到与前一个相同的错误。elem'
Powers