如何声明hasEq约束?

时间:2017-03-08 16:08:10

标签: fstar

我刚刚开始使用F *,我的意思是我在教程中写了几行。到目前为止,它真的很有趣,我想继续学习。

我自己尝试做的第一件事就是编写一个代表非空列表的类型。这是我的尝试:

type nonEmptyList 'a = l : (list 'a) { l <> [] }

但是我收到了错误

  

验证隐式参数失败:子类型检查失败;预期   type(#6468:输入{(hasEq a @ 0)});得到类型

我知道我在正确的轨道上,因为如果我将列表类型限制为包含字符串,则 工作:

type nonEmptyList = l : (list string) { l <> [] }

我假设这意味着原始示例中的l <> []无效,因为我没有指定'a应该支持相等。问题是,我不能为我的生活弄清楚如何做到这一点。我想这与名为hasEq的更高级别的东西有关,但尝试的事情如下:

type nonEmptyList 'a = l : (list 'a) { hasEq 'a /\ l <> [] }

没有让我到任何地方。本教程不涉及hasEq,我在GitHub仓库中的示例中找不到任何有用的东西,所以现在我卡住了。

2 个答案:

答案 0 :(得分:4)

您在此处正确识别了问题。您在'a定义中使用的类型nonEmptyList未指定,因此无法支持相等性。你的直觉是正确的,你需要通过在其上添加一个改进来告诉F * 'a是一个具有相等性的类型:

为此,您可以编写以下内容:

type nonEmptyList (a:Type{hasEq a}) = l : (list a) { l <> [] }

请注意,我用于该类型的活页夹是a而不是'a。它会导致语法错误,它更有意义,因为它不是&#34;任何&#34;再打字了。 另请注意,如果需要,您可以更精确地将a类型的Universe指定为Type0

答案 1 :(得分:3)

您的分析确实是正确的,并且接受的答案通常会提供正确的解决方案。

但是,对于您的具体示例,您不需要列表元素上的可判定的相等性:您可以使用(list 'a){ ~ (List.isEmpty l) }

供参考,以下是isEmpty

的定义
(** [isEmpty l] returns [true] if and only if [l] is empty  *)
val isEmpty: list 'a -> Tot bool
let isEmpty l = match l with
  | [] -> true
  | _ -> false