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

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

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

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

3 ответов


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

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

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


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

scircuit fb sb = if fb then fb else sb

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

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

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


ленивая оценка означает, что ничего не оценивается, пока это действительно не нужно.