Можете ли вы передать операцию типа «делить на 2» или «вычесть 1», используя только частично примененный оператор, где «добавить 1» выглядит следующим образом:
List.map ((+) 1) [1..5];; //equals [2..6]
// instead of having to write: List.map (fun x-> x+1) [1..5]
То, что происходит: 1 применяется к (+) в качестве первого аргумента, а элемент списка применяется в качестве второго аргумента. Для сложения и умножения этот порядок аргументов не имеет значения.
Предположим, я хочу вычесть 1 из каждого элемента (вероятно, это будет распространенная ошибка новичков):
List.map ((-) 1) [1..5];; //equals [0 .. -4], the opposite of what we wanted
1 применяется к (-) в качестве первого аргумента, поэтому вместо (list_item - 1)
я получаю (1 - list_item)
. Я могу переписать его как добавление отрицательного вместо вычитания положительного:
List.map ((+) -1) [1..5];;
List.map (fun x -> x-1) [1..5];; // this works too
Я ищу более выразительный способ написать что-то вроде ((-) _ 1)
, где _
обозначает заполнитель, как в языке Arc. Это приведет к тому, что 1
будет вторым аргументом -
, поэтому в List.map он будет иметь значение list_item - 1
. Поэтому, если вы хотите отобразить divide by 2
в список, вы можете написать:
List.map ((/) _ 2) [2;4;6] //not real syntax, but would equal [1;2;3]
List.map (fun x -> x/2) [2;4;6] //real syntax equivalent of the above
Можно ли это сделать или мне нужно использовать (fun x -> x/2)
? Кажется, что ближе всего к синтаксису-заполнителю мы можем использовать лямбду с именованным аргументом.