2017-07-11 72 views
0

我正在學習ocaml,所以它可能是微不足道的。「Real World 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) 

我得到這個錯誤:

Error: This pattern matches values of type 'a option but a pattern was expected which matches values of type equal:(Stdio__.Import.string -> Stdio__.Import.string -> bool) -> 'b option

問題出在哪裏?

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

+0

奇怪的是,它對我沒有任何影響 –

+0

可能取決於你的'core'版本。 :) – RichouHunter

回答

4

下面是式簽名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) 

作爲一個側面說明,真實世界OCaml的是已經非常舊的(這就是爲什麼一些例子已經過時),作者正在編寫第二版。