2014-09-03 70 views
0

我开始学习OCaml,并且一直困扰着一个简单的问题。 我想用一个简单的循环来计算我在6行文件中的字母数。 这里是我的代码:在OCaml中使用长度函数

let fi = open_in "example";; 
let string = "";; 
let nb_carac = 0;; 

for i = 0 to 6 do 
    string = input_line fi; 
    nb_carac = (nb_carac + String.length(string)); 
    done;; 

问题是,它似乎并没有什么指望,直接达到EOF。 我收到以下错误信息:

Warning 10: this expression should have type unit. 
Warning 10: this expression should have type unit. 
Exception: End_of_file. 

我真的不明白。我已经单独尝试了每条线,并且他们都工作。我究竟做错了什么?

谢谢!

+0

如果下面的后回答您的问题请[点击接受检查标志](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work)。如果它仍然不能回答你的问题,请在你的问题中添加更多细节,这样有人可以回答它。当您将答案标记为已接受时,它会浮动到顶部,以便其他读者可以尽快看到正在工作的答案,答案的作者将被授予一些声望点。 – 2015-04-02 13:26:06

回答

2

OCaml没有可变的变量。您应该使用tail recursionreferences。阅读任何基本的OCaml教科书或教程。

两条线:

string = input_line fi; 
nb_carac = (nb_carac + String.length(string)); 

被理解为无用相等测试(这可以解释你所得到的警告)。

也许你想:

(* shameful *) 
let string = ref "";; 
let nb_carac = ref 0;; 

然后例如

(* shameful *) 
string := input_line fi; 
nb_carac := !nb_carac + String.length(!string); 

但你应该得到一个非常糟糕的品位,如果你像OCaml中一个功能性的语言代码,以便势在必行。

作为一个经验法则,在OCaml编码时避免变异数据。当然,这条规则有一些重要的例外。

您的练习的正确解决方案是使用不会改变任何数据的尾递归函数。看看OCaml标准库stdlib/list.ml获得一些灵感。

可能是一个更好的解决您的运动开始于

let count_lines_and_characters fil = (* incomplete code, fill the ... *) 
    let rec .... 
    in .... 
;; 

当然诸位应填写....

+0

谢谢,它工作! 这确实很基础。我应该更加小心,并且习惯它。 再次感谢您。 – Neor 2014-09-03 14:04:23

+0

顺便说一句,什么工作?使用像我上面做的参考是一个*耻辱*,你会得到一个不好的成绩。你需要编写一些本地的尾递归函数(我没有为你做这件事,因为*你*需要*想*)。 – 2014-09-03 14:06:02

+0

那么,目的是要找到一种方法来计算文件中的每一个字母与我的教训,直到现在教我... 只是一个练习,以适应语言,一点一点。 – Neor 2014-09-03 14:12:01