Question

This is probably something simple, but I have a .fs file with a simple sample function.

let printHello = printfn "%A" "Hello"

I have set the search path to the .fs file using

>#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

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

Tried Test.printHello();; as well but doesn't work. How do I actually make it print "Hello" to screen?

Was it helpful?

Solution

your current printHello isn't actually a function. To make it a function you need to do

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

noice the (). 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". printHello just has unit type, so does nothing. Compare it to

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

Here printHello is a function. In this case, the function is only executed when it is explicitly called, so this prints "World" then "Hello".

OTHER TIPS

As John already said, your printHello isn't a function - it is a value of type 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 ()). 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).

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.

The function printfn was not partially applied, because you gave it all the parameters it required (so it could just print immediately). 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 "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.

use Lazy:

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

DEMO

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

use Seq:

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

DEMO

> Test.printHello;;
"Hello"
val it : seq<unit> = seq [null]
> Test.printHello;;
"Hello"
val it : seq<unit> = seq [null] //many times
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top