вопрос "если" вопрос - PullRequest
       4

вопрос "если" вопрос

4 голосов
/ 10 июня 2010

Я тестирую некоторый простой код F # для выражения «если», но результат для меня неожиданный:

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

Тем не менее

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

Я бы ожидал, что напечатана только буква "а", но здесь я получил "а" и "б" Интересно, почему так получается? Спасибо!

Ответы [ 4 ]

7 голосов
/ 10 июня 2010

Хао правильно. Вы должны обернуть эти выражения в функции, чтобы сделать их ленивыми. Попробуйте это.

let test c a b = if c then a() else b();;
test true (fun () -> printfn "a") (fun () -> printfn "b");;
6 голосов
/ 10 июня 2010

Возможно, потому что оба вызова функции printfn оцениваются до того, как произойдет тестовый вызов?Если вы хотите, чтобы оба вызова функций были отложены до момента их фактического использования, вы можете захотеть ленивые вычисления или макросы (которых нет у F #).

4 голосов
/ 10 июня 2010

Чтобы быть очень ясным, это по той же причине, что

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

оценивает (3+5) перед вызовом f. Почти все языки, кроме Haskell, работают так (языки по модулю с макросами).

0 голосов
/ 14 июня 2010

Вот ленивая версия для вычислений. F #, кажется, требует аннотации типа, чтобы использовать здесь метод Force. Немного грязно, но это работает.

> let test c a b = 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 = ()
>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...