为什么此F#函数仅运行一次?我打了两次电话,它只运行一次 [英] Why this F# function runs only once? I call twice and it runs only once

查看:80
本文介绍了为什么此F#函数仅运行一次?我打了两次电话,它只运行一次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了以下代码来测试F#中的某些MonteCarlo代码.

I wrote the following code to test some MonteCarlo code in F#.

我的问题是我只能在控制台中看到随机数和"oi".我两次调用oneRun函数,但是看起来它只运行一次.

My problem is I only see the random numbers and the "oi" once in my console. I call two times the oneRun function, but it looks that it only runs once.

这是代码:

let genRandomNumbers count =
    let rnd = System.Random()
    printf "oi "
    List.init count (fun _ -> rnd.NextDouble ())

let oneRun = 
   let numberofClicks = 0
   let randomNumber = genRandomNumbers 50
   let action numberofClicks random = if random <= 0.10 
                                          then numberofClicks+1
                                          else numberofClicks
   randomNumber |> Seq.iter (printf "%f ")
   randomNumber |> List.fold action numberofClicks

[<EntryPoint>]
let main argv = 
    let a = oneRun
    printf "%d " a
    let b = oneRun
    printf "%d " b
    let key_info = Console.ReadKey()
    0 // 

有任何提示吗?想法?

推荐答案

为进一步说明Mankarse的正确注释,用于定义值和函数的F#语法看起来非常相似,因此很容易在它们之间混淆.

To expand a little on Mankarse's correct comment, the F# syntax for defining values and functions looks very similar, so it's easy to get confused between them.

这是一个值:

let sum = 42

这是一个功能:

let addThree x = x + 3

值和函数都可以在其后加上 block ,而不仅仅是一行:

Both values and functions can have blocks following them, not just single lines:

let sumWithSideEffects =
    // This will only be evaluated once
    printfn "Side effect happens here"
    42

let addThree x =
    // This will run every time you call the function
    let result = x + 3
    printfn "Added three to %d and got %d" x result
    result

仅声明名称的let声明是一个值.值仅计算一次,因此值中的任何副作用都只会发生一次.确切的说,何时发生的时间不是语言规范所精确定义的,因此您无法指望何时会发生副作用.另一方面,每次调用函数时都会对其求值.

A let declaration that just declares a name is a value. Values are only evaluated once, so any side effects in the value will happen just once. Exactly when they happen is not defined precisely by the language spec, so you can't count on when the side effects will happen. Functions, on the other hand, are evaluated every time the function is called.

现在,当您有一个不带参数的函数时,如何声明它?好吧,您可以通过给它一个参数来声明它,但是给它一个无关紧要的参数.具体来说,您声明它采用类型为unit的参数. unit类型是F#中的一种特殊类型.它基本上对应于一个空的元组,并写为().

Now, when you have a function that takes no parameters, how do you declare it? Well, you declare it by giving it a parameter, but a parameter that doesn't matter. Specifically, you declare that it takes a parameter of type unit. The unit type is a special type in F#. It basically corresponds to an empty tuple, and is written as ().

请稍等一下空元组类型.如果您有两个bool值的元组,那么该元组可以有多少个可能的值?四:可以是(false, false)(false, true)(true, false)(true, true).如果您的元组仅为一个 bool,则它可能具有两个值:(true)(false).如果您有一个 zero 值的元组(不管是什么类型:bool,int,string等,都没有关系),那么它可能只有一个可能的值:(),空元组.而且由于这是一个只有一个可能值的类型,所以将其称为unit类型.

Think about the empty-tuple type for a minute. If you have a tuple of two bool values, how many possible values can this tuple have? Four: it could be (false, false), or (false, true), or (true, false), or (true, true). If you have a tuple of just one bool, it could have two values: (true) or (false). If you have a tuple of zero values (of whatever type: bool, int, string, doesn't matter), then there's only one possible value it could have: (), the empty tuple. And since that's a type with only one possible value, that's why it's called the unit type.

因此,如果您想要一个函数而不是一个值,但是该函数不需要任何有意义的参数,则可以这样定义:

So if you want a function rather than a value, but that function doesn't need to take any meaningful parameters, you define it like this:

let myFunction () =
    printfn "I'm being called purely for the side effects"

请注意如何在函数名称和unit参数之间放置空格.您实际上没有拥有那里的空间-编写let myFunction() = ...是完全合法的-但我希望您看到()不仅仅是函数声明语法,它是<实际类型的em> actualvalue .当您开始使用功能进行高级操作时,这种区别变得很重要,因此,我希望您现在对此有所了解.

Note how I put a space between the function name and the unit parameter. You don't actually have to have that space there — it's perfectly legal to write let myFunction() = ... — but I want you to see that the () is not just function-declaration syntax, it's an actual value of an actual type. This distinction becomes important when you start doing advanced things with functions, so I want you to be clear about it now.

顺便说一句,通常您会在函数声明中使用参数名称而不是值,但是unit类型被特殊对待:由于unit只有一个可能的值,因此您已经知道函数的值会被调用,因此您实际上并不需要将其分配给名称.因此,F#允许您通过在参数列表中仅包含一个()来声明输入类型为unit的函数,而不是选择一个您实际上不会在函数主体中使用的名称.

BTW, normally you'd have a parameter name in your function declaration rather than a value, but the unit type is treated specially: since there's only one possible value of unit, you already know what value your function will be called with, so you don't really need to assign that to a name anyway. So F# lets you declare a function whose input type is unit by just having a () in the parameter list, instead of making you choose a name that you'd never actually use in the function body.

我希望这可以为您清除一切.

I hope this clears things up for you.

这篇关于为什么此F#函数仅运行一次?我打了两次电话,它只运行一次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆