I am trying to take a desired number of elements out of an input list in OCAML. For example, I call my function as “take” which takes two parameters “my_list” and “x”. Here it is:

let take my_list n =
let acc = ([],0) in
let f (current_list, size) x =
if n = 0 || n < 0 || size > n then ([],0)
else if size < n then ((x::current_group),size + 1) in
let (final_list,_) = List.fold_left f acc n in
List.rev(List.rev final_list)

I got a type error:

This expression has type 'a * 'b but an expression was expected of type 'c list Why is this the case?

I am guessing there is something I need to do with my if…else statement. My reason is that if the desired number of elements I want to take out of my list is true (i.e implement this code if I want to take 3 elements out of the list, no 2), then proceed. Otherwise, keep adding the elements to the current list until it is filled with the desired number of elements I want to take out.

Hello,
I still have the same error. I changed my code. Not everyone can get help when they need it, so if you can give constructive input, that would be helpful. Thank you.

If you don’t have an else case on your if statement, OCaml will assume that the type of the entire expression is unit. (This is somewhat more useful when writing code with side-effects.)

In the future, course questions are to be posted in the class discussion forum, as stated in the syllabus.

But I need an else case to handle the scenario that when n is a valid (i.e i want to take 3 elements out of a list of 5 and I cannot take -1 element out of a list etc.).
> let take my_list n =

let acc = ([],0) in
let f (current_list, size) x =
if n = 0 || n < 0 || size > n then acc
else ((List.rev(x::current_list)),size + 1) in
let (final_list,_) = List.fold_left f acc my_list in
List.rev(List.rev final_list)

My output is odd:

take [1;2;3;4;5;6] 3;;

: int list = [6]

why is that?
Can we finish up this question on here?
Thanks!

let f (current_list, size) x = if size < n then ((x::current_list),size + 1) else (current_list, size) in

let (final_list,_) = List.fold_left f acc my_list in final_list

So I modified my code a little bit. Line 3: if the number of elements I want to take out is 0 or less than 0, then I want to return an empty list. Line 4: Otherwise, I want to start taking out elements in the list. Line 5: If the number of elements in my current list is not equal to n, then I want to keep taking elements until I have n of them. Otherwise, I want to return the current list with n elements I extracted.

if n<=0, the type I want to return is an empty list.
If n > 0, I the type I want to return is also a list.
I tested it out in utop, and the error occurs at

else let f (current_list, size) x = if size < n then ((x::current_list),size + 1) in

Why is there a logical error? My description above does not make sense to you?

let take my_list n =
let acc = ([],0) in
if n = 0 || n < 0 then []
else let f (current_list, size) x =
if size < n then (List.rev(x::current_list),size + 1) else (List.rev current_list,size) in
let (final_list,_) = List.fold_left f acc my_list in List.rev(List.rev final_list)

You could “censor” irrelevant parts of your code (like is done here). For this problem, however, the problem is visible from the behavior of your function on different values of n (I’d show 2-5 for clarity).

Also, note that any code that’s been git pushed is visible to TAs.