Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check in the next 'head' in OCaml is empty?

I'm new at OCaml (and still a novice in learning programming in general) and I have a quick question about checking what kind of string the next element in the string list is.

I want it to put a separator between each element of the string (except for the last one), but I can't figure out how to make the program 'know' that the last element is the last element.

Here is my code as it is now:

let rec join (separator: string) (l : string list) : string = 
 begin match l with
    | []->""
    | head::head2::list-> if head2=[] then head^(join separator list) else head^separator^(join separator list)
 end


let test () : bool =
 (join "," ["a";"b";"c"]) = "a,b,c"
;; run_test "test_join1" test 

Thanks in advance!

like image 737
flymonkey Avatar asked Jan 21 '12 13:01

flymonkey


2 Answers

You're almost there. The idea is breaking down the list in three cases where it has 0, 1 or at least 2 elements. When the list has more than one element, you're safe to insert separator into the output string:

let rec join (separator: string) (l : string list) : string =   
   begin match l with
    | [] -> ""
    | head::[] -> head
    | head::list-> head^separator^(join separator list)  
   end

I have several comments about your function:

  • Type annotation is redundant. Because (^) is string concatenation operator, the type checker can infer types of separator, l and the output of the function easily.
  • No need to use begin/and pair. Since you have only one level of pattern matching, there is no confusion to the compiler.
  • You could use function to eliminate match l with part.

Therefore, your code could be shortened as:

let rec join sep l = 
    match l with
    | [] -> ""
    | x::[] -> x
    | x::xs -> x ^ sep ^ join sep xs

or even more concise:

 let rec join sep = function
    | [] -> ""
    | x::[] -> x
    | x::xs -> x ^ sep ^ join sep xs 
like image 62
pad Avatar answered Sep 27 '22 16:09

pad


The empty list is [], the list with one element is [h] and the list with at least one element is h::t. So your function can be written as:

let rec join separator = function
  | []   -> ""
  | [h]  -> h
  | h::t -> h ^ separator ^ join separator t
like image 25
Thomas Avatar answered Sep 27 '22 15:09

Thomas