Короче говоря, ответ таков: да, Haskell будет ленив в рекурсивных функциях.
Лень &&
не является особым случаем: это следствие его определения:
(&&) :: Bool -> Bool -> Bool
True && y = y
False && _ = False
Здесь лень Хаскелла означает, что он может сопоставить первый аргумент с &&
, и второй аргумент не нужно оценивать, чтобы узнать результат.
Для рекурсивной функции, такой как and
у нас есть определение:
and :: [Bool] -> Bool
and [] = True
and (b:bs) = b && and bs
Это рекурсивное определение, Haskell ленив в том, что значения b
и bs
в непустом списке будут оцениваться только при необходимости:в этом случае определение &&
заставляет нас взглянуть на первый элемент b
, а если он равен False
, то остальные значения bs
не нужно оценивать.
Урок здесь заключается в том, что лень - это то, что Haskell предоставляет благодаря сопоставлению с образцом: когда потребляется достаточное количество входных данных для сопоставления с образцом, остальные могут быть оставлены без оценки до тех пор, пока это не потребуется.