Function remove_half

hi everybody,

i have to write a function remove_half l that returns one element out of two like in this exemple.
exemple: remove_half [‘c’ ; ‘a’ ; ‘t’ ; ‘i’ ; ‘e’];; retourne: [‘c’ ; ‘t’ ; ‘e’]*)
thanks in advance for all

Hello. As in your other post, I will try to give you an idea without giving the full solution.

This is a recursive function on a list. The two constructors for a list are [] and ::, meaning that every list is either [] or x :: xs with x an element and xs another list.

As a first idea, you can match the input list and see what you need to do in each case:

let rec remove_half1 l =
  match l with
  | [] -> (* what to do in the empty case? *)
  | x :: xs -> (* what to do with x? what to do with xs? *)

The problem is that here you want to do a different thing with x according to the position in the list (even or odd). It means you need to know the position when you match on l, so your function must have an additional argument to remember the position.

let rec remove_half2 n l =
  match l with
  | [] -> (* ... *)
  | x :: xs -> if (* test on n *) then (* ... *) else (* ... *)

If you manage to write this remove_half2 it will have the following type:

remove_half2 : int -> `a list -> `a list

but remove_half does not have this int parameter. It means that you need to run remove_half2 with an initial value so that you have the right type for your final function.

let remove_half l = remove_half2 (* initial value *) l

Good luck!

i did that :slight_smile: let rec remove_half n l =
match l with
|
| x :: xs → if List.tl (List.tl l) = then [List.hd (l)] else remove_half (List.tl l);;
but i have an error " Error: This expression has type 'a list → 'a list
but an expression was expected of type 'a list"

You don’t need to use List.tl l nor List.hd l with pattern matching. In the right-hand side of

| x :: xs -> ... (*here*)

x is List.hd l and xs is List.tl.
The type error is due to the fact that remove_half expect two arguments and in

.... else remove_half xs

you are only providing one argument to the function.

i did that but i think tat’s wrong

i did this one let remove_half l =
let rec rm_half n l =
if l = then
else
let fst = hd l in
let rest = tl l in
if n then fst :: (rm_half (not n) rest) else (rm_half (not n) rest) in
rm_half true l;;

but that’ s not clear for me with match with
do you have a suggestions?

You can make your code easier to read for us on this forum by putting between ``` marks like this:

```ocaml
Your code here
```

Your code works, here is a version with some simplifications and syntactic tricks to make it more “idiomatic” OCaml:

let rm_half l =
  let rec aux keep = function
  | [] -> []
  | hd :: tl -> if keep then hd :: aux false tl else aux true tl
  in
  aux true l

Namely:

  • Pattern matching rather than using List.hd and List.tl
  • Using the function ... | ... keyword, equivalent to fun l -> match l with ... | ...
  • Using an auxiliary function and declaring it in the scope of the function that uses it, to make sure that it is not used by mistake.