[英]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.