Что делаетx :: xs'
средний? У меня нет большого функционального опыта, но IIRC в F# 1:: 2:: 3:: [];; создает массив [1,2,3] поэтому, что делает, 'делают?
let rec sum xs =
match xs with
| [] -> 0
| x :: xs' -> x + sum xs'
Думаю, sepp2k уже ответил на большую часть вопроса, но я хотел бы добавить пару моментов, которые могут прояснить, как F # Компилятор / OCaml интерпретирует код и объясняет некоторые общие способы использования.
Что касается символа '
- это просто часть имени (действительный идентификатор начинается с буквы, а затем содержит одну или несколько букв, цифр или '
символы). Обычно он используется, если у вас есть функция или значение, которые очень похожи на другие, но некоторым образом новые или изменены .
В вашем примере xs
- это список, который следует суммировать, а сопоставление с образцом разбивает список и дает вам новый список (без первого элемента), который вам нужно суммировать, поэтому он называется xs '
Другое частое использование - при объявлении локальной служебной функции, которая реализует эту функциональность и принимает дополнительный параметр (обычно при написании хвостового рекурсивного кода):
let sum list =
let rec sum 'list res =
список соответствий с
| [] -> res
| x :: xs -> sum 'xs (res + x)
sum' list 0
Однако я думаю, что обычно есть лучшее имя для функции / значения, поэтому я стараюсь чтобы избежать использования '
при написании кода (я думаю, что он не очень удобочитаемый и, более того, он неправильно раскрашивает в StackOverflow!)
Что касается символа ::
- как уже упоминалось, он используется для создания списков из одного элемента, а список ( 1 :: [2; 3]
создает список [1; 2; 3]
). Однако стоит отметить, что символ можно использовать двумя разными способами, а также он интерпретируется компилятором двумя разными способами.
При создании списка вы используете его как оператор, составляющий список (точно так же, как когда вы используете +
для сложения двух чисел). Однако, когда вы используете его в конструкции match
, он используется как шаблон , который представляет собой другую синтаксическую категорию - шаблон используется для разложения list в элемент и остаток, и он будет успешным для любого непустого списка:
// operator
let x = 0
let xs = [1;2;3]
let list = x::xs
// pattern
match list with
| y::ys -> // ...
'- это просто часть имени переменной. И да foo :: bar
, где foo - это элемент типа a, а bar - список типа a, означает «список, в котором foo является первым элементом, за которым следуют элементы bar». Таким образом, значение оператора match таково:
Если xs - пустой список, значение равно 0. Если xs - это список, содержащий элемент x, за которым следуют элементы в xs '
, значение равно x + сумма xs '
. Поскольку x
и xs '
являются новыми переменными, это приводит к тому, что для любого непустого списка x
будет присвоено значение первого элемента и xs '
будет назначен список, содержащий все остальные элементы.
Как уже говорили другие, «это перенос из математики, где x» можно было бы сказать как «x простое»
В языках семейства ML идиоматично называть переменную foo '
, чтобы указать, что она в некоторой степени связана с другой переменной foo
, особенно в рекурсиях, подобных вашему примеру кода. Как и в императивных языках, вы используете i
, j
для индексов цикла. Это соглашение об именах может быть немного неожиданным, поскольку '
обычно является недопустимым символом для идентификаторов в C-подобных языках.