简体   繁体   English

Printfn值不是函数,不能在F#的交互窗口中应用

[英]Printfn value is not a function and cannot be applied in F#'s interactive window

This is probably something simple, but I have a .fs file with a simple sample function. 这可能很简单,但我有一个带有简单示例函数的.fs文件。

let printHello = printfn "%A" "Hello"

I have set the search path to the .fs file using 我已经使用了.fs文件的搜索路径

>#I "PathToMyFSFile"

I have loaded my file using 我已经加载了我的文件

>#load "Test.fs"

Which worked fine. 哪个工作正常。 Now I want to call the function which actually prints the hello to screen, but thats turning out to be too difficult 现在我想调用实际打印hello到屏幕的功能,但事实证明这太难了

> Test.printHello;;
val it : unit = ()

Tried Test.printHello();; 试过Test.printHello();; as well but doesn't work. 同样但不起作用。 How do I actually make it print "Hello" to screen? 我如何让它在屏幕上打印“Hello”?

your current printHello isn't actually a function. 你当前的printHello实际上并不是一个函数。 To make it a function you need to do 要使它成为您需要做的功能

let printHello() = printfn "%A" "Hello"

noice the () . noice () Then everything should work. 一切都应该有效。

EDIT: 编辑:

When the compiler sees your definition 当编译器看到您的定义时

let printHello = printfn "%A" "Hello"

it passes it as a simple data term. 它将其作为简单的数据术语传递。 For example, consider this program: 例如,考虑这个程序:

let printHello = printfn "%A" "Hello"
printfn "World"
printHello

This will print "Hello" then "World" . 这将打印"Hello"然后打印"World" printHello just has unit type, so does nothing. printHello只有单位类型,所以什么都不做。 Compare it to 比较它

let printHello() = printfn "%A" "Hello"
printfn "World"
printHello()

Here printHello is a function. 这里printHello是一个函数。 In this case, the function is only executed when it is explicitly called, so this prints "World" then "Hello" . 在这种情况下,该函数仅在显式调用时执行,因此打印"World"然后"Hello"

As John already said, your printHello isn't a function - it is a value of type unit . 正如约翰已经说过的,你的printHello不是一个函数 - 它是一个unit类型的值。 When you give printfn all the required arguments (as you did), it does the imperative operation and return unit (which is a type with only a single value written as () ). 当你给printfn所有必需的参数时(正如你所做的那样),它会执行命令操作和返回unit (这是一个只有一个值写为() )。 You can see that writing that declaration does the printing immediately: 您可以看到编写该声明立即进行打印:

> let printHello = printfn "%A" "Hello";;
"Hello"
val printHello : unit = ()

When you use printHello later, it simply refers to this unit value (which does not carry any information). 稍后使用printHello ,它只是引用此unit值(不包含任何信息)。

If you want to make it a function (of type unit -> unit ) that will do something each time it is executed, then you can use the sample that John posted. 如果你想让它成为一个函数( unit -> unit类型unit -> unit ),每次执行它都会做一些事情,那么你可以使用约翰发布的样本。

The function printfn was not partially applied , because you gave it all the parameters it required (so it could just print immediately). printfn函数未部分应用 ,因为您为它提供了所需的所有参数(因此它可以立即打印)。 If you wanted to use partial application, you could use something like: 如果您想使用部分应用程序,可以使用以下内容:

> let printHello = printfn "%s %s" "Hello";; // Note - didn't give value for second %s
val printHello : string -> unit

Now printHello is a function that waits for the second parameter and then runs: 现在printHello是一个等待第二个参数然后运行的函数:

> printHello "World";;
Hello World
val it : unit = ()

> printHello "F#";;
Hello F#
val it : unit = ()

As has already been said in other answers, "printHello" set to () is unit, the return value of printfn is () , console print is side-effect. 正如在其他答案中已经说过的那样,“printHello”设置为()是单位,printfn的返回值是(),控制台打印是副作用。

use Lazy: 使用懒惰:

let printHello = Lazy (fun () ->printfn "%A" "Hello")

DEMO DEMO

> Test.printHello.Value;;
"Hello"
val it : unit = ()
> Test.printHello.Value;;
val it : unit = () //only once

use Seq: 使用Seq:

let printHello = seq { printfn "%A" "Hello"; yield ()}

DEMO DEMO

> Test.printHello;;
"Hello"
val it : seq<unit> = seq [null]
> Test.printHello;;
"Hello"
val it : seq<unit> = seq [null] //many times

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

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