Поиск…


Вступление

Синтаксис вызова функции Haskell, объясненный с помощью сравнений с языками языка C, где это применимо. Это направлено на людей, которые приезжают в Haskell с фона на языках C-стиля.

замечания

В общем случае правило для преобразования вызова функции C-стиля в Haskell в любом контексте (назначение, возврат или встроенный в другой вызов) заключается в замене запятых в списке аргументов стиля C пробелом и перемещении открытия скобки из вызова стиля С, чтобы содержать имя функции и ее параметры.

Если какие-либо выражения полностью заключены в круглые скобки, эти (внешние) пары круглых скобок могут быть удалены для удобочитаемости, поскольку они не влияют на значение выражения.
Существуют и другие обстоятельства, при которых скобки могут быть удалены, но это влияет только на читаемость и удобство обслуживания.

Скобки в вызове базовой функции

Для вызова функции стиля C, например

plus(a, b); // Parentheses surrounding only the arguments, comma separated

Тогда эквивалентный код Haskell будет

(plus a b) -- Parentheses surrounding the function and the arguments, no commas

В Haskell круглые скобки явно не требуются для приложения-приложения и используются только для устранения неоднозначности выражений, например, в математике; поэтому в тех случаях, когда скобки окружают весь текст в выражении, скобки на самом деле не нужны, и следующее также эквивалентно:

plus a b -- no parentheses are needed here!

Важно помнить, что в языках C-стиля функция

Круглые скобки во встроенных вызовах функций

В предыдущем примере мы не нуждались в круглых скобках, потому что они не влияли на смысл выражения. Однако они часто необходимы в более сложном выражении, как показано ниже.
В C:

plus(a, take(b, c));

В Haskell это становится:

(plus a (take b c))
-- or equivalently, omitting the outermost parentheses
plus a (take b c)

Обратите внимание, что это не эквивалентно:

plus a take b c -- Not what we want!

Можно подумать, что, поскольку компилятор знает, что функция take является функцией, она сможет узнать, что вы хотите применить ее к аргументам b и c и передать ее результат в plus .
Однако в Haskell функции часто принимают другие функции в качестве аргументов, и между фактическими различиями между функциями и другими значениями мало фактического различия; и поэтому компилятор не может принять ваше намерение просто потому, что take - это функция.

Итак, последний пример аналогичен следующему вызову функции C:

plus(a, take, b, c); // Not what we want!

Частичное применение - часть 1

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

(((plus) 1) 2)

Здесь функция (plus) применяется к 1 давая функцию ((plus) 1) , которая применяется к 2 , что дает функцию (((plus) 1) 2) . Поскольку plus 1 2 - это функция, которая не принимает аргументов, вы можете считать ее простой; однако в Haskell существует небольшое различие между функциями и значениями.

Чтобы подробнее остановиться, функция plus - это функция, которая добавляет свои аргументы.
Функция plus 1 - это функция, которая добавляет 1 к ее аргументу.
Функция plus 1 2 - это функция, которая добавляет 1 к 2 , что всегда является значением 3 .

Частичное применение - часть 2

В качестве другого примера у нас есть map функций, которая принимает функцию и список значений и применяет функцию к каждому значению списка:

map :: (a -> b) -> [a] -> [b]

Предположим, мы хотим увеличить каждое значение в списке. Вы можете определить свою собственную функцию, которая добавляет ее в свой аргумент и map эту функцию над вашим списком.

addOne x = plus 1 x
map addOne [1,2,3]

но если у вас есть другой взгляд на определение addOne , с добавлением круглых скобок для акцента:

(addOne) x = ((plus) 1) x

Функция addOne , применяемая к любому значению x , такая же, как частично примененная функция plus 1 примененная к x . Это означает, что функции addOne и plus 1 идентичны, и мы можем избежать определения новой функции, просто заменив addOne на plus 1 , не забывая использовать круглые скобки для выделения plus 1 в качестве подвыражения:

map (plus 1) [1,2,3]


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow