如何声明一个 hasEq 约束?
How to declare a hasEq constraint?
我刚开始使用 F*,我的意思是我已经在教程中写了几行。到目前为止它真的很有趣,我想继续学习。
我尝试自己做的第一件事是编写一个表示非空列表的类型。这是我的尝试:
type nonEmptyList 'a = l : (list 'a) { l <> [] }
但我收到错误
Failed to verify implicit argument: Subtyping check failed; expected
type (a#6468:Type{(hasEq a@0)}); got type Type
不过我知道我的方向是正确的,因为如果我将列表类型限制为包含字符串, 会起作用:
type nonEmptyList = l : (list string) { l <> [] }
我假设这意味着原始示例中的 l <> []
无效,因为我没有指定 'a
应该支持相等性。问题是我一辈子都弄不明白该怎么做。我想这与称为 hasEq
的更高类型有关,但尝试诸如:
type nonEmptyList 'a = l : (list 'a) { hasEq 'a /\ l <> [] }
没有带我去任何地方。本教程不涵盖 hasEq
,而且我在 GitHub 存储库的示例中找不到任何有用的信息,所以现在我被卡住了。
您正确地确定了这里的问题。您在 nonEmptyList
的定义中使用的类型 'a
未指定,因此无法支持相等性。您的直觉是正确的,您需要告诉 F* 'a
是一个具有相等性的类型,方法是对其进行细化:
为此,您可以编写以下内容:
type nonEmptyList (a:Type{hasEq a}) = l : (list a) { l <> [] }
请注意,我用于该类型的活页夹是 a
而不是 'a
。它会导致语法错误,它更有意义,因为它不再是 "any" 类型。
另外,请注意,如果需要,您可以更精确地将 a
类型的宇宙指定为 Type0
。
你的分析确实正确,采纳的答案大体上给出了正确的解决方案。
不过,对于您的具体示例,您不需要列表元素上的可判定相等性:您可以只使用 (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
我刚开始使用 F*,我的意思是我已经在教程中写了几行。到目前为止它真的很有趣,我想继续学习。
我尝试自己做的第一件事是编写一个表示非空列表的类型。这是我的尝试:
type nonEmptyList 'a = l : (list 'a) { l <> [] }
但我收到错误
Failed to verify implicit argument: Subtyping check failed; expected type (a#6468:Type{(hasEq a@0)}); got type Type
不过我知道我的方向是正确的,因为如果我将列表类型限制为包含字符串, 会起作用:
type nonEmptyList = l : (list string) { l <> [] }
我假设这意味着原始示例中的 l <> []
无效,因为我没有指定 'a
应该支持相等性。问题是我一辈子都弄不明白该怎么做。我想这与称为 hasEq
的更高类型有关,但尝试诸如:
type nonEmptyList 'a = l : (list 'a) { hasEq 'a /\ l <> [] }
没有带我去任何地方。本教程不涵盖 hasEq
,而且我在 GitHub 存储库的示例中找不到任何有用的信息,所以现在我被卡住了。
您正确地确定了这里的问题。您在 nonEmptyList
的定义中使用的类型 'a
未指定,因此无法支持相等性。您的直觉是正确的,您需要告诉 F* 'a
是一个具有相等性的类型,方法是对其进行细化:
为此,您可以编写以下内容:
type nonEmptyList (a:Type{hasEq a}) = l : (list a) { l <> [] }
请注意,我用于该类型的活页夹是 a
而不是 'a
。它会导致语法错误,它更有意义,因为它不再是 "any" 类型。
另外,请注意,如果需要,您可以更精确地将 a
类型的宇宙指定为 Type0
。
你的分析确实正确,采纳的答案大体上给出了正确的解决方案。
不过,对于您的具体示例,您不需要列表元素上的可判定相等性:您可以只使用 (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