繁体   English   中英

无法生成随机数F#

[英]Unable to generate random number F#

我正在研究一个小项目,我正在尝试学习F#的功能方式,由于一些奇怪的原因,我无法生成随机数,因此无法获得随机日期。 这是我的F#代码

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

let n = rand.Next(10)确实生成一个随机数但不在匹配块中

任何建议都会受到欢迎

谢谢

您的代码没有按照您的预期执行。 模式匹配在技术上与构建数据相反。 它只是分解/解构数据。

你在这做什么:

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

具有以下含义:

  1. 检查funToNight是否为元组。
  2. 将元组的第一个值赋给value
  3. 将元组的第二个值赋给n

看起来你的期望是:

  1. 检查元组的第二个值是否在n

这不是模式匹配的工作原理。

您可以通过向模式匹配添加when子句来添加条件,例如将值与预定义变量进行比较。 像这样:

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

但在我看来,你的案例正是一个用例,模式匹配开始时没有意义。 您想检查第二个条目是否是随机数,因此请改用if语句。

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

而不是fstsnd你也可以在lambda中做到。

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

这是选择的一般解决方案,也适用于其他大小的元组。 fstsnd只适用于具有两个元素的元组。

除此之外,您可能希望使用List.tryPick而不是List.pick 如果List.pick找不到元素,则抛出异常。 顶部变量应以小写字母开头。 大写值用于类型/类。

所以这是一个完整的工作示例:

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!"

附录

List.pick调用返回了不少None ,并且不挑一个条目。 原因是您在传递给List.pick的lambda函数中生成随机数。

您当前的代码“流”是这样的。 你仔细阅读清单。 首先采摘("Sara",1) 你生成一个随机的,比方说5 15不匹配,因此将使用下一个条目("Saima", 2) 但是你再次生成一个新的随机数,让我们说3并且选择下一个条目,因为32不相等。 这可以继续,而不是每次选择任何条目。 即使你将随机生成更改为rand.Next(6)

所以一般的建议是你不应该为lambda表达式添加副作用。 我假设您要生成一个随机数,然后从列表中选择它。 通过提取lambda之外的随机调用很容易改变。

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

所以一般建议,避免高阶函数的副作用。

你真正的问题根本不是随机数,而是你的match声明。 你误解了它是如何工作的。 短版本: match (whatever) with (value, n) -> ...不会做你认为它做的事情:它总是匹配,并将名称valuen分配给你匹配的任何元组的两个部分。

较长的版本是你犯了与F#相同的错误:不理解匹配..所以我只是指出你的问题来阅读更深入的答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM