Вы, вероятно, знакомы с синтаксисом let
для определения функции:
let f x = x + 1 in …
Этот синтаксис можно использовать где угодно, в том числе в теле функции.Теперь, если вам случится использовать имя внутренней функции в качестве возвращаемого значения внешней функции, внешняя функция будет возвращать функцию.
let outer_function x =
let inner_function y = x + y in
inner_function
Синтаксис let
фактически является синтаксическим сахаром для fun
или function
.В частности, если вы определите inner_function
просто для использования имени один раз, вы можете также использовать нотацию fun
и не беспокоиться о присвоении внутренней функции имени.
let outer_function x =
fun y -> x + y
Кроме того, если всевнешняя функция делает, когда вы передаете ей аргумент, чтобы создать и вернуть внутреннюю функцию, а затем рассмотреть ее поведение, когда вы передадите этой функции два аргумента.Сначала внешняя функция строит внутреннюю функцию, используя ее первый (и единственный) аргумент;затем эта внутренняя функция применяется ко второму аргументу, поэтому ее тело выполняется.Это эквивалентно наличию только одной функции, которая принимает два аргумента.Это наблюдение известно как curry .
let outer_function x y = x + y
Обратите внимание, что тип этой функции int -> int -> int
;это тот же тип, что и int -> (int -> int)
(оператор типа стрелки является ассоциативно-правым).
Каррирование не применяется, когда внешняя функция выполняет некоторую работу перед созданием внутренней функции.В этом случае работа выполняется после получения первого аргумента.
let outer_function x =
print_endline "outer";
fun y -> print_endline "inner"; x + y
Таким образом, структура вашего кода может выглядеть следующим образом:
let lv (c : cfg) : blabel -> ide set =
let c' = do_some_precomputation c in
fun (bl : blabel) -> (… : ide set)