Насколько я знаю, GHC никогда не сделает более ленивым , чем указано программистом, даже если он может доказать, что это не меняет семантику термина. Я не думаю, что есть какая-либо фундаментальная причина избегать изменения лени термина, когда мы можем доказать, что семантика не меняется; Я подозреваю, что это скорее эмпирическое наблюдение, что мы не знаем ни одной ситуации, когда это было бы действительно отличной идеей. (И если преобразование изменит семантику, я бы посчитал ошибкой для GHC внести это изменение.)
На ум приходит только одно возможное исключение, так называемое преобразование "полной лени", которое хорошо описано в вики . Короче, GHC переведет
\a b -> let c = {- something that doesn't mention b -} in d
до
\a -> let c = {- same thing as before -} in \b -> d
, чтобы избежать повторного вычисления c
каждый раз, когда аргумент применяется к новому b
. Но мне кажется, что эта трансформация больше связана с запоминанием, чем с ленью: мне кажется, что два приведенных выше термина имеют одинаковую (денотационную) семантику с ленью / строгостью и отличаются только в функциональном отношении.