Есть два способа интерпретировать этот вопрос. Во-первых, зачем писать map (\x -> x * x)
, когда мы можем написать
doubleIt x = x * x
... map doubleIt ...
Ответ таков: у вас может быть следующее:
foo y zs = map (\x -> x^y) zs
и тогда нет полностью прямого преобразования, позволяющего полностью переместить анонимную функцию на верхний уровень.
Мы могли бы написать
foo y zs = map (powerIt y) xs
powerIt y = ?
и тогда мы обнаружим, что powerIt y = \x -> x^y
! (конечно, вы можете перевести x обратно во внешнее определение, но в этом случае вы действительно захотите (хотя синтаксически Haskell не заставляет вас) написать (powerIt y)
как (\x -> powerIt y x)
.
Когда у вас есть функции первого класса, им необходимо закрыться по своей среде, а это означает, что вам нужен некоторый способ представить функцию, которая может ссылаться на вещи в лексическом область, где это объявлено. Это сила лямбд!
Теперь, другой вопрос, почему бы не переместить анонимные функции на соответствующий уровень, который не является верхним, и таким образом получить, например,
foo y zs = let powerIt x = x^z
in map powerIt zs
В таком случае, подумайте о том, что на самом деле означает let. Фактически, мы можем преобразовать let в несколько лямбд следующим образом: foo ys zs = (\powerIt -> map powerIt zs) (\x -> x^y)
Теперь, в реальных реализациях, не все эти десугарации происходят именно так, и иногда компиляторы по-разному обрабатывают различные предложения по причинам, связанным с эффективностью. Но основная вещь остается - лямбды очень мощные и экспансивные и могут дать нам основной язык, о котором просто и легко думать, несмотря на разнообразие форм связывания, которые мы накладываем поверх них.
Без лямбды у нас есть язык, на котором мы можем определять переменные и мы можем определять функции, а затем мы можем иногда делать определенные вещи с функциями. С лямбдами у нас есть язык, где функции являются значениями, как и любое другое значение, и у нас есть один набор единообразных способов присвоения имен чему-либо.
Инверсия перспективы состоит в том, чтобы рассматривать лямбды не как особый случай, а как общий случай, а все другие различные механизмы связывания имен - как сахар для них.