0

Here is what I have and the error that I am getting sadly is

Error: This function has type 'a * 'a list -> 'a list
       It is applied to too many arguments; maybe you forgot a `;'. 

Why is that the case? I plan on passing two lists to the deleteDuplicates function, a sorted list, and an empty list, and expect the duplicates to be removed in the list r, which will be returned once the original list reaches [] condition.

will be back with updated code

let myfunc_caml_way arg0 arg1 = ...

rather than

let myfunc_java_way(arg0, arg1) = ...

Then you can call your function in this way:

myfunc_caml_way "10" 123

rather than

myfunc_java_way("10, 123)
ShahrukhKhan
  • 365
  • 1
  • 3
  • 11

3 Answers3

1

I don't know how useful this might be, but here is some code that does what you want, written in a fairly standard OCaml style. Spend some time making sure you understand how and why it works. Maybe you should start with something simpler (eg how would you sum the elements of a list of integers ?). Actually, you should probably start with an OCaml tutorial, reading carefully and making sure you aunderstand the code examples.

let deleteDuplicates u = 
  (*
    u : the sorted list
    v : the result so far
    last : the last element we read from u
  *)
  let rec aux u v last = 
    match u with 
        [] -> v
      | x::xs when x = last -> aux xs v last
      | x::xs -> aux u (x::v) x
  in
  (* the first element is a special case *)
  match u with
      [] -> []
    | x::xs -> List.rev (aux xs [x] x)
Jbeuh
  • 395
  • 1
  • 6
0

You seem to be thinking that OCaml uses tuples (a, b) to indicate arguments of function calls. This isn't the case. Whenever some expressions stand next to each other, that's a function call. The first expression is the function, and the rest of the expressions are the arguments to the function.

So, these two lines:

append(first,r)
deleteDuplicates(remaining, r)

Represent a function call with three arguments. The function is append. The first argument is (first ,r). The second argument is deleteDuplicates. The third argument is (remaining, r).

Since append has just one argument (a tuple), you're passing it too many arguments. This is what the compiler is telling you.

You also seem to be thinking that append(first, r) will change the value of r. This is not the case. Variables in OCaml are immutable. You can't do anything that will change the value of r.

Update

I think you have too many questions for SO to help you effectively at this point. You might try reading some OCaml tutorials. It will be much faster than asking a question here for every error you see :-)

Nonetheless, here's what "match failure" means. It means that somewhere you have a match that you're applying to an expression, but none of the patterns of the match matches the expression. Your deleteDuplicates code clearly has a pattern coverage error; i.e., it has a pattern that doesn't cover all cases. Your first match only works for empty lists or for lists of 2 or more elements. It doesn't work for lists of 1 element.

Jeffrey Scofield
  • 65,646
  • 2
  • 72
  • 108
  • with the append(first, r) I am not hoping to change the value of r, but to add to r. How do I then deal with my situation? So essentially each line in O'Caml has to be recursive, that is in the if statement's code, I have to have only one call? – ShahrukhKhan Feb 06 '14 at 01:04
  • Adding to r changes the value of r, doesn't it? Basically you want to think of your OCaml code as calling functions, then passing the returned values to other functions. To make it clearer, you can give names to intermediate values with `let`: `let newr = append (first, r) in deleteDuplicates (remaining, newr)`. – Jeffrey Scofield Feb 06 '14 at 01:06
  • My end goal is to have a new list so I can add to it. if lists are immutable, then how do I add to them? I figured append would do the job :( use cons to to get the first and second element, compare them, if same, add it to the darn list(the new one, of course); – ShahrukhKhan Feb 06 '14 at 01:26
  • 1
    Same answer as before: you don't add to your existing list, you create a new list that's longer. – Jeffrey Scofield Feb 06 '14 at 02:23
  • I figured it out, although it only works for small numbers, and for larger numbers I get Exception: Match_failure ("//toplevel//", 405, 0). Also, why do you use 'in' – ShahrukhKhan Feb 06 '14 at 02:27
  • Every `let` has an `in`, except at the top level of a module. I think I pointed this out once before. It would be good to read some tutorials on OCaml, I think. You have too many questions for SO to be helpful at this point. – Jeffrey Scofield Feb 06 '14 at 02:29
  • Thanks, and I appreciate your help, but I can't figure out why I'm getting the Match_Failure //toplevel error, I even Googled it... – ShahrukhKhan Feb 06 '14 at 02:37
0

This is not a direct answer to your question.

The standard way of defining an "n-ary" function is

let myfunc_caml_way arg0 arg1 = ...

rather than

let myfunc_java_way(arg0, arg1) = ...

Then you can call your function in this way:

myfunc_caml_way "10" 123

rather than

myfunc_java_way("10, 123)

See examples here:

By switching from myfunc_java_way to myfunc_caml_way, you will be benefited from what's called "Currying"

However please note that you sometimes need to enclose the whole invocation by parenthesis

myfunc_caml_way (otherfunc_caml_way "foo" "bar") 123

in order to tell the compiler not to interpret your code as

((myfunc_caml_way otherfunc_caml_way "foo") "bar" 123)
Community
  • 1
  • 1
nodakai
  • 7,773
  • 3
  • 30
  • 60