简体   繁体   中英

OCaml list syntax error

I am writing a function to remove neighbors from a list which have the same value. I don't understand what the syntax error is here. This is what I have:

let rec rem_dup_neighb l = 
let rec rem_dup_neighb_aux l lastseen retl = 
match l with 
 []->retl
|[()]->[()]
| (y::rest) -> if(y==lastseen) then rem_dup_neighb_aux l lastseen retl else rem_dup_neighb_aux l y (y::retl)
in rem_dup_neighb_aux l 9000 [];;

I get the following error for the last line of the function:

Error: This expression has type int but an expression was expected of type
     unit

As an example, if you pass in [1;2;2;3;5] to the function, it should return [1;2;3;5]

Any help is appreciated. Thanks

UPDATE: Function seems to be infinite looping:

let rec rem_dup_neighb l = 
let rec rem_dup_neighb_aux l lastseen retl = 
match l with []->retl
| (y::rest) -> if(y==lastseen) then rem_dup_neighb_aux l lastseen retl else rem_dup_neighb_aux l y (y::retl)
in
    match l with
    (lastseen::rest) ->  rem_dup_neighb_aux l lastseen []

UPDATE 2: wasn't reducing the problem per iteration. Function seems to be returning [5;3;2] instead of [1;2;3;5] now though.

let rec rem_dup_neighb l = 
let rec rem_dup_neighb_aux l lastseen retl = 
match l with []->retl
| (y::rest) -> if(y==lastseen) then rem_dup_neighb_aux rest lastseen retl else rem_dup_neighb_aux rest y (y::retl)
in
    match l with
    []->[]
    |(lastseen::rest) ->  rem_dup_neighb_aux l lastseen []

UPDATE 3:

let rec rem_dup_neighb l = 
let rec rem_dup_neighb_aux l lastseen retl = 
match l with []->retl
| (y::rest) -> if(y==lastseen) then rem_dup_neighb_aux rest lastseen retl else rem_dup_neighb_aux rest y (y::retl)
in
    match l with
    []->[]
    |(lastseen::rest) ->  rem_dup_neighb_aux l lastseen [lastseen]

If one of the test cases has [()] as input, then you can't use 9000 as a fake value for the beginning of the list. You need to have a fake value of the same type as whatever is in the list. One idea would be to use the actual first value of the list.

As a side comment, it seems like you should just take out your second case in the match. By the second case, I mean the pattern that (after fixing up the code) matches a list of length one; ie, the pattern [_] . With your approach (using a "last seen" value) there are only two cases, for empty and non-empty lists. Your special problems come at the beginning of the list (as you're experiencing now), not at the end.

Update

You can have a pattern match (a match expression) anywhere you like. So, you can have one after the in :

let rem_dup_neighbors aList =
    let rec aux l lastseen retl =
        ...
    in
    match aList with
    | pattern1 -> blah blah blah
    | pattern2 -> aux blah blah

Update 2

When calling yourself recursivelly, you have to pass a smaller problem. Your auxiliary function just keeps calling itself with the same list.

The match clause [()] -> [()] accepts and produces a unit list , which doesn't really make sense there. You probably should have written [_] -> retl , _ being the match syntax for "match anything".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM