簡體   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