user2236919
user2236919

Reputation: 33

How to find minimum of a tuples list

I have to find a minimum of a tuples list but I only want to return the minimum of snd element of the tuples, not the entire tuple. Unfortunately i'm having the following error in the following code and I don't know why. The l argument is a list of tuples (float * float)

let rec minRight l = match l with
    | [] -> raise (Arg.Bad "minRight: empty list")
    | [x]-> x
    | (_,y)::xs -> min y (minRight xs)

Error:

| (_,y)::xs -> min y (minRight xs)
Error: This expression has type 'a but an expression was expected of type
         'b * 'a

Thanks in advance.

Upvotes: 2

Views: 1977

Answers (3)

Chris
Chris

Reputation: 36496

We can break this down into two separate problems. First you need to get just the second elements from each tuple. Then you need to find the minimum of those values.

The first parts is easy:

let min_right = function
  | [] -> invalid_arg "Empty list."
  | lst -> lst |> List.map snd

Now, we can use List.fold_left to get the minimum. Providing the first value as the initial minimum to List.fold_left we only need to map over the tail of the list (which may be empty).

let min_right = function
  | [] -> invalid_arg "Empty list."
  | (_, y)::tl -> 
    tl
    |> List.map snd
    |> List.fold_left min y 

But if you feel that iterating over the list entirely to strip the second element from each before then iterating over the whole thing again to find the minimum is repetitive, future OCaml offers sequences. As of OCaml 4.07 - July 2018.

let min_right = function
  | [] -> invalid_arg "Empty list."
  | (_, y)::tl -> 
    tl
    |> List.to_seq 
    |> Seq.map snd
    |> Seq.fold_left min y 

Upvotes: 0

jrouquie
jrouquie

Reputation: 4405

Here is one problem, in addition to the ones mentioned in previous answers: the line

| [x]-> x

returns a tuple, while you said you want to "return the minimum of snd element[s] of the tuples".

Upvotes: 2

Jeffrey Scofield
Jeffrey Scofield

Reputation: 66818

I think maybe your problem is that you named your function min, but you also want to use the standard OCaml function min. Is that possible?

OCaml doesn't have overloading (as compensation it has parametric polymorphism). So you need to use different names for things.

Upvotes: 1

Related Questions