使用Janestreet Core_kernel映射

时间:2018-02-13 01:21:55

标签: ocaml

我正在使用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苦苦挣扎的菜鸟

1 个答案:

答案 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语法,表示该值作为第一类模块传递。

参考文献:

  1. https://ocaml.janestreet.com/ocaml-core/latest/doc/core_kernel/Core_kernel/Map/#type-comparator
  2. https://ocaml.janestreet.com/ocaml-core/latest/doc/core_kernel/Core_kernel/Comparator/module-type-S/