开发者

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)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜