2011-10-04 31 views
1

我想在OCaml中創建一個函數,返回一個文件中每個字符出現頻率的映射。例如,考慮一個文件,其中包含此:如何在OCaml中的文件中構建字符出現頻率的映射?

AAAAA BB C 

該輸入會產生這種地圖:

{ ' ' -> 2, 'A' -> 5, 'B' -> 2, 'C' -> 1 } 

這是我到目前爲止有:

let usage = "usage: "^Sys.argv.(0)^" [OPTION]... [FILE]..." 
let file = ref "" 
let speclist = [ 
    ("-z", Arg.String (fun c -> file := c), " compress [FILE]"); 
    ("-d", Arg.String (fun d -> file := d), " decompress [FILE]"); 
] 

let build_freq_map f = 
    let channel = open_in f in 
    function x -> 
    input_byte channel 

let() = 
    Arg.parse 
    speclist 
    (fun x -> raise (Arg.Bad ("Bad argument: "^x))) 
    usage; 

    build_freq_map !file; 

但是,這並不編譯,說:

File "main.ml", line 19, characters 1-22: 
Error: This expression has type 'a -> int 
     but an expression was expected of type unit 

如何修改我的代碼,以便build_frequency_map返回文件字符和頻率的映射?

回答

3

你的錯誤很簡單,不言自明。 build_freq_map !file有一個函數類型(它返回一個函數)。您的模式與()即單元類型匹配。所以類型不匹配。

它看起來像你的程序有點不完整,因爲它不輸出任何內容或對結果從build_freq_map得到任何結果。此外,我沒有看到build_freq_map中的任何邏輯實際上會構建您所需的「地圖」。所以你還有一段路要走。

+0

是的,一旦我開始編譯,對邏輯的工作就是下一步。這絕對是不完整的。如何修改代碼,以便我不針對單元類型進行模式匹配? (這是我的第一個OCaml程序。) – rps

+0

沒關係,我想通了。謝謝。 – rps

+0

在調用'build_freq_map!file'之前,有一個隱含的'let()='。由於'build_freq_map'返回一個函數而不是單位,這就是編譯錯誤。爲了解決這個問題,你需要處理那個回報。你可以綁定一個變量,或者在函數調用之前使用下劃線('let _ =')。 – nlucaroni