2014-02-18 24 views
1

我刚刚开始OCaml(和函数式编程),我试着编写一个函数来计算数组(tab)中出现“value”的次数。 我想:OCaml在过滤器上的语法错误

let rec count_occ tab value = 
    let rec count_rec idx time = function 
     | tab.length - 1 -> time 
     | _ when tab.(indice) == value-> count_rec (idx + 1) (time + 1) 
     | _ -> count_rec (indice + 1) time 
    in 
    count_rec 0 0 
;; 

不幸的是,它不会因为语法错误的编译,我没有找到解决办法。

回答

3
let rec count_occ tab value = 

上面这个rec​​是没有必要的。

let rec count_rec idx time = function 
     | tab.length - 1 -> time 

您无法匹配表达式。你想要像下一行那样使用警卫,或者使用if语句来测试类似的事情。 tab.length也不存在,因为tabarray,而不是具有length字段的记录。你想要Array.length tab

真的,虽然你根本不想要functionfunctionfun x -> match x with相同,并且暗示count_rec具有类型int -> int -> int -> int

 | _ when tab.(indice) == value-> count_rec (idx + 1) (time + 1) 

indices未被声明;让我们假设你的意思是idx。另外,==是物理上的平等,你真的想要=

 | _ -> count_rec (indice + 1) time 
    in 
    count_rec 0 0 

,你已经开了个好头,你递归的基本原理是正确的,虽然一个边缘的情况下是不正确的,但你应该能够解决一个小问题,一旦你有固定的语法问题。

+0

谢谢,我在正确的道路,现在,我的代码来看:http://pastie.org/8746861但它并没有真正的工作 – Epitouille

+0

当你使用|匹配idx时您正在创建'idx'到'n'的新绑定,而不是测试'n'的内容是否等于'idx'。相反,这是在警卫中完成的。匹配是结构性的,如分解列表和元组并匹配变体和常量。 – nlucaroni

+0

一旦你解决了这个问题,你应该立即注意到在这种情况下匹配不合适 - 在这三种情况下你都会与'_'匹配。改用if语句。 – nlucaroni

1

finnaly我后我的最终代码:

let count_occ tab value = 
    let rec count_rec idx time = 
     if (Array.length tab) = idx then 
      time 
     else if (tab.(idx)) = value then 
      count_rec (idx + 1) (time + 1) 
     else 
      count_rec (idx + 1) time 
    in 
    count_rec 0 0 
;; 
+1

看起来不错! “tab。(idx)”和“idx = Array.length tab”周围的额外括号可以为您节省_precious_ keystrokes;)。 – nlucaroni