在for循环中返回记录的F#调用函数只执行一次

时间:2017-05-27 16:28:53

标签: f# functional-programming

我主要在C#工作,不熟悉F#/函数语言,而且我对一个非常简单的程序有问题。 我有一个函数创建一个包含两个整数字段的记录。在System.Random.NextDouble内选择match字段以符合某些概率。然后我有一个for循环,应该运行createCustomer函数四次。

我遇到的问题是,Customer对于for循环的所有10次迭代都是相同的,printfn内的getIATime似乎只执行一次。

Program.fs

open Simulation

[<EntryPoint>]
let main argv = 
    printfn "%A" argv
    printfn "Test"

    for i in 1 .. 10 do
        let mutable customer = createCustomer
        printfn "i: %d\tIA: %d\tService: %d" i customer.interArrivalTime customer.serviceTime


    ignore (System.Console.ReadLine()) //Wait for keypress @ the end
    0 // return an integer exit code

Simulation.fs

module Simulation

type Customer = {
    interArrivalTime: int
    serviceTime: int
}

let createCustomer =
    let getRand =
        let random = new System.Random()
        fun () -> random.NextDouble()

    let getIATime rand =
        printf "Random was: %f\n" rand 
        match rand with
        | rand when rand <= 0.09 -> 0
        | rand when rand <= 0.26 -> 1
        | rand when rand <= 0.53 -> 2
        | rand when rand <= 0.73 -> 3
        | rand when rand <= 0.88 -> 4
        | rand when rand <= 1.0 -> 5

    let getServiceTime rand =
        match rand with
        | rand when rand <= 0.2 -> 1
        | rand when rand <= 0.6 -> 2
        | rand when rand <= 0.88 -> 3
        | rand when rand <= 1.0 -> 4

    {interArrivalTime = getIATime (getRand()); serviceTime = getServiceTime (getRand())}

1 个答案:

答案 0 :(得分:4)

您的getCustomer不是功能,而是。它的主体在程序初始化期间只执行一次,结果存储在一个字段中,然后可以访问该字段。当您认为自己“调用”该函数时,实际上只是引用该值。没有打电话,因为没有什么可以打电话。

要使getCustomer成为函数,请为其指定一个参数。这就是函数与F#中的值的不同之处:如果你有一个参数,那么你就是一个函数;如果不是 - 你是一个价值观。由于没有您想要传递给函数的实际数据,因此可以为其指定类型为unit的“虚拟”(“占位符”)参数。此类型只有一个值,该值写为()

let createCustomer () =
    let getRand =
        let random = new System.Random()
        fun () -> random.NextDouble()

    ...

然后这样称呼:

for i in 1 .. 10 do
    let mutable customer = createCustomer()
    printfn "i: %d\tIA: %d\tService: %d" i customer.interArrivalTime customer.serviceTime