来自" Real World Ocaml"的示例代码没有按预期运行。

时间:2017-07-11 08:42:27

标签: ocaml

我学习ocaml所以它可能是微不足道的。

当我尝试构建此代码的可执行文件时:

open Core.Std

let build_counts () =
  In_channel.fold_lines stdin ~init:[] ~f:(fun counts line ->
    let count =
      match List.Assoc.find counts line with
      | None -> 0
      | Some x -> x
    in
    List.Assoc.add counts line (count + 1)
  )

let () =
  build_counts ()
  |> List.sort ~cmp:(fun (_,x) (_,y) -> Int.descending x y)
  |> (fun l -> List.take l 10)
  |> List.iter ~f:(fun (line,count) -> printf "%3d: %s\n" count line)

我收到此错误:

  

错误:此模式匹配类型'选项的值          但是预计会匹配类型值的模式            等于:(Stdio __。Import.string - > Stdio __。Import.string - > bool) - >            ' b选项

问题出在哪里?

链接:https://realworldocaml.org/v1/en/html/files-modules-and-programs.html

1 个答案:

答案 0 :(得分:5)

以下是List.Assoc.find的类型签名:

('a, 'b) Base__List.Assoc.t -> equal:('a -> 'a -> bool) -> 'a -> 'b option

第一个参数是关联列表(示例中为counts)。最后一个参数(类型'a)是您要查找的密钥(在您的示例中为line)。然而,另一个论点'a -> 'a -> bool标有equal。它非常简单,它是List.Assoc.find用来查看两个键是否相等的比较函数。

如果'astring,则简单的(=)就足够了。您可以使用以下内容替换match行来修复代码:

match List.Assoc.find counts ~equal:(=) line with

List.Assoc.add函数遵循相同的模式。您应该使用以下内容替换build_counts函数的最后一行:

List.Assoc.add counts ~equal:(=) line (count + 1)

作为附注,Real World OCaml已经相当陈旧(这就是为什么有些例子已经过时),作者正在制作第二版。