Что означает :: и 'в oCaml? - PullRequest
6 голосов
/ 27 февраля 2010

Что означает x :: xs'? У меня нет большого функционального опыта, но IIRC в F # 1 :: 2 :: 3 :: [] ;; создает массив [1,2,3] так что же делать?

let rec sum xs =
  match xs with
    | [] -> 0
    | x :: xs' -> x + sum xs'

Ответы [ 5 ]

15 голосов
/ 27 февраля 2010

Я думаю, sepp2k уже ответил на большинство вопросов, но я хотел бы добавить пару моментов, которые могут прояснить, как F # / OCaml-компилятор интерпретирует код, и объяснить некоторые общие применения.

Относительно символа ' - это просто часть имени (допустимый идентификатор начинается с буквы, а затем содержит одну или несколько букв, цифр или ' символов). Обычно он используется, если у вас есть функция или значение, очень похожее на какое-то другое, но каким-то образом new или изменение .

  • В вашем примере xs - это список, который должен быть суммирован, а сопоставление с образцом разлагает список и дает вам новый список (без первого элемента), который нужно суммировать, поэтому он называется xs'

  • Другое частое использование - это объявление локальной функции полезности, которая реализует эту функциональность и принимает дополнительный параметр (как правило, при написании хвостово-рекурсивного кода):

    let sum list =
      let rec sum' list res = 
        match list with
        | [] -> res
        | x::xs -> sum' xs (res + x)
      sum' list 0
    

Тем не менее, я думаю, что обычно есть более подходящее имя для функции / значения, поэтому я стараюсь избегать использования ' при написании кода (я думаю, что он не особо читабелен и, кроме того, не правильно раскрашивает StackOverflow!)

Относительно символа :: - как уже упоминалось, он используется для создания списков из одного элемента и списка (1::[2;3] создает список [1;2;3]). Однако стоит отметить, что символ можно использовать двумя различными способами, и он также интерпретируется компилятором двумя различными способами.

При создании списка вы используете его как оператор, который создает список (так же, как при использовании + для добавления двух чисел). Однако, когда вы используете его в конструкции match, он используется как шаблон , который является другой синтаксической категорией - шаблон используется для декомпозиции списка в элемент и остаток, и это успешно для любого непустого списка:

// operator
let x = 0
let xs = [1;2;3]
let list = x::xs

// pattern
match list with
| y::ys -> // ...
6 голосов
/ 27 февраля 2010

'является просто частью имени переменной. И да foo :: bar, где foo - это элемент типа a, а bar - это список типа a, что означает «список, в котором foo является его первым элементом, за которым следуют элементы bar». Таким образом, значение выражения соответствия:

Если xs - пустой список, значение равно 0. Если xs - список, содержащий элемент x, за которым следуют элементы в xs', значение равно x + sum xs'. Поскольку x и xs' являются свежими переменными, это приводит к тому, что для любого непустого списка x будет присвоено значение первого элемента, а xs' будет назначен список, содержащий все другие элементы.

2 голосов
/ 28 февраля 2010

Как и другие говорили, «это переход от математики, где х» будет сказано как «х простое»

1 голос
/ 27 февраля 2010

В языках семейства ML идиоматично называть переменную foo', чтобы указать, что она в некоторой степени связана с другой переменной foo, особенно в рекурсиях, подобных вашему примеру кода. Как и в императивных языках, вы используете i, j для индексов цикла. Это соглашение об именах может быть немного удивительным, поскольку ' обычно является недопустимым символом для идентификаторов в языках, подобных C.

0 голосов
/ 26 января 2013

Что означает x :: xs'?

Если у вас есть две переменные с именами x и xs', тогда x :: xs' создает новый список с x, добавленным впереди xs'.

У меня нет большого функционального опыта, но IIRC в F # 1 :: 2 :: 3 :: [] ;; создает массив [1,2,3]

Не совсем. Это список.

так, что делает '

Он рассматривается как алфавитный символ, поэтому следующее эквивалентно:

let rec sum xs =
  match xs with
  | [] -> 0
  | x :: ys -> x + sum ys

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...