【发布时间】:2019-11-11 18:26:08
【问题描述】:
我正在尝试从book 学习 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)
但是在执行这段代码时出现了一些奇怪的错误,即“Sort Error in Refinement”。我无法理解并解决此错误。
任何帮助将不胜感激。
编辑:来自 Liquid Haskell 书:
谓词要么是原子谓词,通过比较获得 两个表达式,或者,谓词函数对列表的应用 论据...
在 Liquid Haskell 逻辑语法中,允许的谓词之一是:e r e 其中r 是原子二元关系(函数只是一种特殊的关系)。
此外,在教程中,他们将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 @-}
现在我在Powers 的类型定义中将elem 替换为elem'。但我仍然得到与上一个相同的错误。
【问题讨论】:
-
elem是一个变量,而不是中缀运算符。另外,elem 是在哪里定义的? -
@ThomasM.DuBuisson 呃,
Prelude? -
@JosephSible 但是液体haskell的前奏是否包含
elem的提升逻辑版本是这里真正的问题。 -
我问是因为(诚然过时的)“尝试液体 Haskell”在线不知道
elem是什么所以我怀疑@kishlaya 必须为使用液体 Haskell 提供合适的定义定义Powers并细化类型检查log2。 -
@ThomasM.DuBuisson 我已经用相关细节编辑了我的问题。
标签: haskell types liquid-haskell