Использование конструктора варианта варианта только с одним значением кортежа - PullRequest
7 голосов
/ 19 марта 2012
# type foo = Foo of int * int
# let t = (1, 2)
# Foo t
Error: The constructor Foo expects 2 argument(s),
   but is applied here to 1 argument(s)

Почему я должен сделать Foo (1, 2), чтобы избежать этой ошибки, даже если t имеет соответствующий тип?

Ответы [ 2 ]

12 голосов
/ 19 марта 2012

На мой взгляд, это одна из проблемных частей синтаксиса OCaml.Несмотря на то, как это выглядит, конструктор Foo не требует двух кортежей в качестве аргумента.Синтаксически требуется два значения в скобках - но они не являются кортежами.Так что это просто тот случай, когда t имеет неправильный тип.Чтобы сделать эту работу, нужно сказать:

let (a, b) = t in Foo (a, b)

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

Редактировать : если вы хотите , то конструктор Foo может взять один кортеж, а не два отдельныхзначения, вы можете определить его следующим образом:

type foo = Foo of (int * int)

Тогда остальная часть вашего исходного кода будет работать.

5 голосов
/ 20 марта 2012

Обратите внимание, что различие между Foo of (a * b) и Foo of a * b существует по соображениям эффективности: Foo of (a * b) имеет аргумент, который является кортежем, указателем на два элемента в куче.Foo of a * b имеет два аргумента, которые непосредственно упакованы тегом, избегая косвенного обращения.

Это также причина, почему, например, алгоритмы, которые используют списки ассоциаций (например, Hashtables со связанными списками) иногда определяютих собственный тип данных вместо повторного использования ('a * 'b) list:

type ('a, 'b) assoc_list =
  | Nil
  | Cons of 'a * 'b * ('a, 'b) assoc_list

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

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