我正在使用Ocaml 4.06,emacs / merlin进行真实世界的Ocaml。 请参阅以下代码段。我有两个问题:
open Core_kernel
let () =
let digit_alist = [ 0, "zero"; 1, "one"; 2, "two" ; 3, "three"; 4, "four";
5, "five"; 6, "six"; 7, "seven"; 8, "eight"; 9, "nine" ] in
let _ = Map.of_alist_exn digit_alist ~comparator:Int.comparator in
()
从merlin评估时,它显示两个错误。看起来Map.of_alist_exn
不接受带标签的参数~comparator
。:
This expression has type (int * string) list
but an expression was expected of type
('a, 'b) Core_kernel.Map.comparator =
(module Core_kernel__.Comparator.S with type comparator_witness = 'b and type t = 'a)
The function applied to this argument has type
('a * 'b) Core_kernel__.Import.list -> ('a, 'b, 'c) Base__Map.t
This argument cannot be applied with label ~comparator
Q1)功能类型Map.of_alist_exn
是否已更改?
我认为功能类型已经改变。所以我改变了这样的源代码:
open Core_kernel
let () =
let digit_alist = [ 0, "zero"; 1, "one"; 2, "two" ; 3, "three"; 4, "four";
5, "five"; 6, "six"; 7, "seven"; 8, "eight"; 9, "nine" ] in
let _ = Map.of_alist_exn Int.comparator digit_alist in
()
此时,梅林抱怨这样:
This expression has type
(Core_kernel.Int.t, Core_kernel.Int.comparator_witness)
Core_kernel__.Comparator.comparator =
(Core_kernel.Int.t, Core_kernel.Int.comparator_witness)
Base__Comparator.t
but an expression was expected of type
('a, 'b) Core_kernel.Map.comparator =
(module Core_kernel__.Comparator.S with type comparator_witness = 'b and type t = 'a)
我希望Int.comparator
将扮演有效比较器的角色,但是ocaml认为它是无效的。
Q2)我应该为比较器提供什么?
@A苦苦挣扎的菜鸟
答案 0 :(得分:1)
查看comparator
的定义,我们可以看到它定义如下,
type ('k, 'cmp) comparator = (module Comparator.S with type comparator_witness = 'cmp and type t = 'k)
在ocaml中,模块可以用作第一类值。该功能的一个有趣结果是模块现在可以定义为类型,并作为函数参数/参数传递/使用。 Janestreet core_kernel
和/或base
充分利用了您发现的第一类模块。 Map.comparator
就是这样一个用例。
Comparator.S
定义如下:
module type Core_kernel.Comparator.S
type t
type comparator_witness
val comparator : (t, comparator_witness) comparator
如果你在module Int
中查看#show Core_kernel.Int
- utop
的模块签名,那么我们可以看到它定义Core_kernel.Comparator.S
模块中规定的类型和函数类型。
因此,Map.of_alist_exn
接受(module Int)
作为有效参数。 (module Int)
是ocaml语法,表示该值作为第一类模块传递。
参考文献: