这可能很简单,但我有一个带有简单示例函数的.fs文件。
let printHello = printfn "%A" "Hello"
我已使用
将搜索路径设置为.fs文件>#I "PathToMyFSFile"
我已经使用
加载了我的文件>#load "Test.fs"
哪个工作正常。现在我想调用实际打印hello到屏幕的功能,但那确实太难了
> Test.printHello;;
val it : unit = ()
尝试过Test.printHello();;同样但不起作用。我如何让它在屏幕上打印“Hello”?
答案 0 :(得分:6)
您当前的printHello
实际上并不是一个功能。要使它成为你需要做的功能
let printHello() = printfn "%A" "Hello"
noice ()
。一切都应该有效。
编辑:
当编译器看到你的定义时
let printHello = printfn "%A" "Hello"
它将其作为简单的数据术语传递。例如,请考虑以下程序:
let printHello = printfn "%A" "Hello"
printfn "World"
printHello
这将打印"Hello"
然后"World"
。 printHello
只有单位类型,所以什么都不做。将它与
let printHello() = printfn "%A" "Hello"
printfn "World"
printHello()
这里printHello
是一个函数。在这种情况下,该函数仅在显式调用时执行,因此打印"World"
然后"Hello"
。
答案 1 :(得分:5)
正如John已经说过的那样,printHello
不是函数 - 它是unit
类型的值。当您给printfn
所有必需的参数(就像您所做的那样)时,它会执行命令操作并返回unit
(这是一种只有一个值写为()
的类型)。您可以看到编写该声明立即进行打印:
> let printHello = printfn "%A" "Hello";;
"Hello"
val printHello : unit = ()
稍后使用printHello
时,它只会引用此unit
值(不包含任何信息)。
如果你想使它成为一个函数(类型为unit -> unit
),每次执行它时都会执行某些操作,那么你可以使用John发布的样本。
函数printfn
不是部分应用,因为您为它提供了所需的所有参数(因此它可以立即打印)。如果您想使用部分应用程序,可以使用以下内容:
> let printHello = printfn "%s %s" "Hello";; // Note - didn't give value for second %s
val printHello : string -> unit
现在printHello
是一个等待第二个参数然后运行的函数:
> printHello "World";;
Hello World
val it : unit = ()
> printHello "F#";;
Hello F#
val it : unit = ()
答案 2 :(得分:1)
正如在其他答案中已经说过的那样,“printHello”设置为()是单位,printfn的返回值是(),控制台打印是副作用。
使用Lazy:
let printHello = Lazy (fun () ->printfn "%A" "Hello")
<强>样本强>
> Test.printHello.Value;;
"Hello"
val it : unit = ()
> Test.printHello.Value;;
val it : unit = () //only once
使用Seq:
let printHello = seq { printfn "%A" "Hello"; yield ()}
<强>样本强>
> Test.printHello;;
"Hello"
val it : seq<unit> = seq [null]
> Test.printHello;;
"Hello"
val it : seq<unit> = seq [null] //many times