Подтвердить что ты не робот

Короткое замыкание (&&) в Haskell

Быстрый вопрос, который в последнее время подслушивал меня. Выполняет ли Haskell весь тест эквивалентности в функции, возвращающей логическое значение, даже если возвращается ложное значение?

Например

f a b = ((a+b) == 2) && ((a*b) == 2)

Если первый тест возвращает false, выполнит ли он второй тест после &&? Или Хаскелл достаточно ленив, чтобы не делать этого и двигаться дальше?

4b9b3361

Ответ 1

Должно быть короткое замыкание, как и другие языки. Он определен как в прелюдии:

(&&)                    :: Bool -> Bool -> Bool
True  && x              =  x
False && _              =  False

Итак, если первый параметр False, второй никогда не нужно оценивать.

Ответ 2

Как сказал Мартин, языки с ленивой оценкой никогда не оценивают что-то, что значение не требуется немедленно. На ленивом языке, таком как Haskell, вы получаете короткое замыкание бесплатно. В большинстве языков || и && и аналогичные операторы должны быть построены специально на языке, чтобы они могли провести короткое замыкание. Однако в Haskell ленивая оценка делает это ненужным. Вы можете определить функцию, которая сама замыкается на короткое замыкание:

scircuit fb sb = if fb then fb else sb

Эта функция будет вести себя так же, как логический оператор "или". Вот как || определяется в Haskell:

True  || _ = True
False || x = x

Итак, чтобы дать вам конкретный ответ на ваш вопрос, нет. Если левая часть || верно, правая сторона никогда не оценивается. Вы можете поместить два и два вместе для других операторов, которые "короткое замыкание".

Ответ 3

Ленивая оценка означает, что ничто не оценивается, пока оно действительно не понадобится.