F# - broken "then"
I'm at the moment trying to make a very simple app that will greet depending on the time of the day. My code is:
open System
let read() = Console.Read()
let readLine() = Console.ReadLine()
let clockMsg min max todo =
if (DateTime.Now.Hour > min) && (DateTime.Now.Hour < max) then todo
let name = readLine()
clockMsg 0 8 <| printfn "Go to bed, %s!" name
clockMsg 8 12 <| printfn "Good morning, %s!" name
clockMsg 12 18 <| printfn "Good afternoon, %s!" name
read() |> ignore
Now is my ques开发者_如何学Pythontion, how can only ONE of the function calls be valid, but all three will no matter what, print their messages?
Agree with BrokenGlass. What you probably want to do is:
clockMsg 0 8 (fun() -> printfn "Go to bed, %s!" name)
and this change in clockMsg
:
let clockMsg min max todo =
if (DateTime.Now.Hour > min) && (DateTime.Now.Hour < max) then todo()
clockMsg 0 8 <| printfn "Go to bed, %s!" name
This passes the result of the printfn
function to your clockMsg
function - so it is evaluated before clockMsg even runs, this is the reason you see all messages.
Also since it returns nothing (or more specific a result of type unit
() ) you will see in the debugger that todo
is always passed as null
.
just to mention another way: you can pass lazy<_> as argument:
open System
let read() = Console.Read()
let readLine() = Console.ReadLine()
let clockMsg min max (todo : Lazy<_>) =
if (DateTime.Now.Hour > min) && (DateTime.Now.Hour < max) then todo.Value
let name = readLine()
clockMsg 0 8 <| lazy(printfn "Go to bed, %s!" name)
clockMsg 8 12 <| lazy(printfn "Good morning, %s!" name)
clockMsg 12 18 <| lazy(printfn "Good afternoon, %s!" name)
精彩评论