Jacob
Jacob

Reputation: 19

How do I make an implementation of List.allPairs with List.map?

So far, I've made a function which matches all elements of one list with only the first element of another list, but I need it to match all elements of list 1 with all elements of list 2.

My code so far looks like this:

let prototype (lst1: 'a list) (lst2: 'b list) =
    List.map (fun i -> [i,lst2.Head]) lst1 |> List.concat

Upvotes: 1

Views: 116

Answers (1)

Fyodor Soikin
Fyodor Soikin

Reputation: 80744

So you figured out how to pair all elements of lst1 with a single thing. Great!

Now look: inside the map's parameter, you have the exact same problem - pair every element of lst2 with i. So you can just solve it the exact same way:

let prototype (lst1: 'a list) (lst2: 'b list) =
    List.map (fun i -> List.map (fun j -> [i, j]) lst2 |> List.concat) lst1 |> List.concat

But this is a bit ugly of course. There are a few minor modifications you can make to make it prettier.

First, note that List.map >> List.concat is equivalent to List.collect:

let prototype (lst1: 'a list) (lst2: 'b list) =
    List.collect (fun i -> List.collect (fun j -> [i, j]) lst2) lst1

But of course a much better option is to use list comprehensions:

let prototype (lst1: 'a list) (lst2: 'b list) =
  [ for i in lst1 do 
      for j in lst2 ->
        i, j
  ]

Upvotes: 2

Related Questions