let test cab = if c then a e...">

"if" question of expression

I am testing a simple F # code for the expression "if", but for me this is unexpected:

> let test cab = if c then a else b;; val test : bool -> 'a -> 'a -> 'a 

However

 > test true (printfn "a") (printfn "b");; a b val it : unit = () 

I expect only β€œa” to be printed, but here I got both β€œa” and β€œb”. I wonder why this happens? Thanks!

+4
source share
4 answers

Perhaps because both calls to the printfn function are evaluated before the test call ever occurs? If you want both function calls to be deferred until they are used, you might want lazy evaluation or macros (which F # is).

+6
source

Hao is correct. You have to wrap these expressions in functions to make them lazy. Try it.

 let test cab = if c then a() else b();; test true (fun () -> printfn "a") (fun () -> printfn "b");; 
+7
source

To be extremely clear, for the same reason that

 let fx = x + 1 f (3+5) 

evaluates (3+5) before calling f . Almost every language except Haskell works like this (modulo languages ​​with macros).

+4
source

Here is the lazy version of the calculations. F # seems to require type annotations in order to use the Force method here. A bit messy, but it works.

 > let test cab = if c then (a:Lazy<unit>).Force else (b:Lazy<unit>).Force;; val test : bool -> Lazy<unit> -> Lazy<unit> -> (unit -> unit) > test true (lazy (printfn "a")) (lazy (printfn "b"))();; a val it : unit = () > 
0
source

Source: https://habr.com/ru/post/1312375/


All Articles