F# - Result is list of list of int instead of a list of int

77 views Asked by At

I have quite a complex problem that I have simplified for the purpose of this question.

Let's just say the problem is as follow:
I want a list of the first 3 numbers (1,2,3) added to all of these numbers: 0,10,20

So I want the following desired output:

all = [1; 2; 3; 11; 12; 13; 21; 22; 23]  

This is the code I have written:

let r = [0;10;20];;
let r2 = [1..3];;
let rshift value = r2 |> List.map (fun (x)-> x  + value)  
let all = r |> List.map (fun x-> rshift x)  

The actual output is:

val allshift : int list list = [[1; 2; 3]; [11; 12; 13]; [21; 22; 23]]

As you can see, this is a list of a list of ints, instead of just one long list of int. How can I get the desired output from above?

Thanks for your help!

2

There are 2 answers

0
FoggyFinder On BEST ANSWER

There are many ways. Here are some of them:

let adder1 l1 l2 = 
    l1 
    |> List.map(fun x -> l2 |> List.map(fun y -> y + x))
    |> List.concat

let adder2 l1 l2 = 
    l1 
    |> List.collect(fun x -> l2 |> List.map(fun y -> y + x))

let adder3 l1 l2 = 
    l1 
    |> List.fold(fun acc x -> acc @ (l2 |> List.map(fun y -> y + x))) []

let r = [0;10;20]
let r2 = [1..3]

adder1 r r2 |> printfn "%A"
adder2 r r2 |> printfn "%A"
adder3 r r2 |> printfn "%A"

Print:

[1; 2; 3; 11; 12; 13; 21; 22; 23]
[1; 2; 3; 11; 12; 13; 21; 22; 23]
[1; 2; 3; 11; 12; 13; 21; 22; 23]

Link: https://dotnetfiddle.net/oUpZna

0
Random Dev On

For cases like this I kinda like the list-comprehension syntax, because it seems to be more readable for most people - so here is another possibility on top of what Foggy gave you:

let addAllCombinations xs ys = 
    [ for y in ys do for x in xs -> (x+y) ]

obvious usage:

> addAllCombinations [1;2;3] [0;10;20];;
val it : int list = [1; 2; 3; 11; 12; 13; 21; 22; 23]

the obvious generalization is of course

let combineWith op xs ys = 
    [ for y in ys do for x in xs -> op x y ]

here:

> combineWith (+) [1..3] [0;10;20];;
val it : int list = [1; 2; 3; 11; 12; 13; 21; 22; 23]

you should be able to use this for your complex problem too (or so I hope)

fun-fact this function is sometimes (yeah it's Haskell ...) known as liftM2 as it lifts (+) into the list-monad ...