Unable to generate random number F#

f#, functional-programming

Solution

Your code doesn't do what you expect it to do. Pattern Matching is technically the opposite of constructing data. It just decompose/de-construct data.

What you do here:

match funToNight with                    
| (value,n ) -> Some value
|_ -> None

has the following meaning:

- Check if `funToNight` is a tuple.

- Assign the first value of the tuple to `value`

- Assign the second value of the tuple to `n`

It seems what you expected was:

- Check if the second value of a tuple is what is inside `n`

And that isn't how Pattern Matching works.

You can add conditionals like comparing a value with a pre-defined variable by adding a `when` clause to the Pattern Matching. Like this:

match funToNight with
| (value,x) when x = n -> Some value
| _ -> None

But in my opinion, your case is exactly a use-case where Pattern Matching don't make sense to begin with. You want to check if the second entry is your random number, so use an `if` statement instead.

let MyGirlFriend  =
    List.pick (fun funToNight  ->
        let n = rand.Next(10)
        if   (snd funToNight) = n
        then Some (fst funToNight)
        else None
    ) IfancyHerList

instead of `fst` and `snd` you also can do it in the lambda.

let MyGirlFriend =
    List.pick (fun (name,nr)  ->
        let n = rand.Next(10)
        if   nr = n
        then Some name
        else None
    ) IfancyHerList

This is the general solution to pick that also works with tuples of other sizes. `fst` and `snd` only work with tuples that has exactly two elements.

Besides that you probably want to use `List.tryPick` instead of `List.pick`. `List.pick` throws an exception if it cannot find an element. On top variables should start with a lower-case. Upper-case values are used for Types/Classes.

So here is a complete working example:

let rand = new System.Random()

let ifancyHerList =
    [
        ("Sara",1); ("Saima",2); ("Zoe",3); ("Scarlett",4);
        ("Jennifer",5);("Sandra Bullock",6)
    ]

let myGirlFriend =
    List.tryPick (fun (name,nr)  ->
        let n = rand.Next(10)
        if   nr = n
        then Some name
        else None
    ) ifancyHerList

match myGirlFriend with
| Some name -> printfn "Your date for tonight is %A lucky fella" name
| None      -> printfn "You don't have a date tonight!"

Addendum

Your `List.pick` call returns quite a lot `None` and doesn't pick an entry. The reason is that you generate the random number inside the lambda function you pass to `List.pick`.

Your current "flow" of your code is like this. You go through the list. First picking `("Sara",1)`. You generate a random, let's say `5`. `1` and `5` doesn't match so the next entry `("Saima", 2)` will be used. But then you generate again a new random number, let's say `3` and the next entry is picked because `3` and `2` are not equal. This can go on without every picking any entry. Even if you change the random generation to `rand.Next(6)`.

So a general advice is that you shouldn't add side-effects to lambda expressions. I assume you want to generate one random number and then pick it from the list. Its easy to change by extracting the random call outside the lambda.

let myGirlFriend =
    let n = rand.Next(10)
    List.tryPick (fun (name,nr) ->
        if   nr = n
        then Some name
        else None
    ) ifancyHerList

So a general advice, avoid side-effects in Higher-Order functions.

Problem

I am working on a small project and am trying to learn F# the functional way ,for some strange reason I am unable to generate a random number and as such unable to get a random date. here is my F# code ``` let IfancyHerList = [("Sara",1); ("Saima",2); ("Zoe",3);("Scarlett",4); ("Jennifer",5);("Sandra Bullock",6)] let MyGirlFriend = List.pick (fun funToNight -> let n = rand.Next(10) match funToNight with | (value,n ) -> Some value |_ -> None) IfancyHerList printfn "Your date for tonight is %s lucky fella" MyGirlFriend ``` The let n = rand.Next(10) does generate a random number but not in match block any suggestion would be most welcome thanks

Original source