Скобки в Окамле - PullRequest
       7

Скобки в Окамле

5 голосов
/ 10 октября 2011

Я оцениваю очень простой кусок кода на верхнем уровне Ocaml:

let p5 () = print_int 5;;
p5 ();;

print_string "*************************";;

let p4 = print_int 4;;
p4;; 

И он возвращает:

val p5 : unit -> unit = <fun>
#   5- : unit = ()
#   *************************- : unit = ()
#   4val p4 : unit = ()
#   - : unit = ()

Мои вопросы

  1. Что означает () в let p5 () = print_int 5;;?
  2. Что означают - и () в # 5- : unit = ()?
  3. Является ли p4 функцией?
  4. Почему в начале # 4val p4 : unit = () стоит 4?
  5. Похоже, что в коде Ocaml можно использовать (), чтобы скрыть побочный эффект, может кто-нибудь показать мне пример?

Ответы [ 4 ]

11 голосов
/ 10 октября 2011

Вот несколько ответов:

  1. () - это значение типа единицы. Тип блока - это тип с одним значением. Это обычно используется для создания функций, которые либо не возвращают ничего значащего, либо не принимают ничего значащего. Помните, что в OCaml все функции всегда должны что-то возвращать и принимать некоторые аргументы, поэтому тип блока используется, чтобы обойти это ограничение. Представьте, что это похоже на тип void в C, C ++ или Java.
  2. Есть две чередующиеся строки. 5 печатается функцией print_int, а не верхним уровнем. Верхний уровень просто возвращает - : unit = () без 5. Верхний уровень говорит вам, что он не создал никаких новых привязок - и что последнее возвращаемое значение имеет тип unit и имеет значение ().
  3. Нет. Он не принимает никаких аргументов, поэтому он не является функцией.
  4. Опять чередуются две строки. 4 печатается функцией print_int. В это время уровень верхнего уровня сообщает вам, что он создал новую привязку p4, что эта переменная содержит значение типа unit и что сохраненное значение равно ().
  5. Нет, () не используется для скрытия побочных эффектов. Обычно он используется для создания функций, которые имеют побочные эффекты и, следовательно, не требуют каких-либо аргументов.
6 голосов
/ 10 октября 2011

LiKao уже объяснил все ключевые моменты, но я подумал, что может иметь больше смысла, если вы вводите свои определения по одной строке за раз, которая показывает, какие ответы приходят от каких входных данных. Строки, введенные человеком, начинаются с #.

# let p5 () = print_int 5;;
val p5 : unit -> unit = <fun>

Это определяет p5 как функцию, которая принимает значения типа unit и возвращает значения типа unit. Существует только одно значение типа unit, которое записывается как (). Так что это именно те скобки, о которых вы спрашиваете (я думаю). Обратите внимание, что () в вашем определении является шаблоном для значений, принимаемых функцией. Как шаблон, () соответствует самому себе (как и все константы, используемые в качестве шаблонов).

# p5 ();;
5- : unit = ()

Это немного сбивает с толку. 5 записывается вашей функцией p5. Остальное - ответ от верхнего уровня OCaml. Это говорит о том, что результат вашего выражения имеет тип unit и имеет значение (). Это имеет смысл, print_int имеет тип int -> unit.

# print_string "*************************";;
*************************- : unit = ()

Здесь похожая путаница. Звездочки * написаны print_string. Остальное показывает результат, который снова имеет тип unit со значением ().

# let p4 = print_int 4;;
4val p4 : unit = ()

То же самое и здесь. 4 написано print_int. Остальное показывает, что верхний уровень определил символ с именем p4, тип которого unit и значение (). Опять же, это имеет смысл, потому что print_int возвращает тип unit, а () - единственное значение этого типа. По типу p4 можно сказать, что это , а не функция. Функции имеют стрелку (->) в типе. p4 это просто значение типа unit.

# p4;;
- : unit = ()

Здесь вы запрашиваете у верхнего уровня тип и значение p4, и он сообщает вам (снова), что p4 имеет тип unit и имеет значение ().

2 голосов
/ 03 мая 2012

Ваш последний вопрос, как () используется, чтобы «скрыть побочный эффект».Вы, вероятно, имеете в виду отложенную оценку функции.Вот пример:

 let p x = print_string "abc";;
 let q = print_string "abc";;

Существует существенная разница между p и q.Разница в том, что p является функцией типа 'a -> unit, а q является значением типа unit.Когда вы определяете p, ничего не печатается.Строка «abc» будет напечатана, только когда вы применяете функцию p к аргументу, то есть когда вы оцениваете p 1 или p "blah" или что-то еще.(Функция p принимает аргументы любого типа и игнорирует их.) Так что в случае p внутри функции «скрыт побочный эффект».

Бессмысленно иметьАргумент «x» в определении «px», поскольку «x» вообще не используется.Поэтому для простоты используется тип «unit», поэтому определение «p» выглядит как «let p () = ...».Это то же самое, что и

 let p = fun () -> print_string "abc";;

Функция «p» затем используется как «p ()».Это может сбивать с толку, если вы впервые изучили языки программирования, такие как C, Java и т. Д., Где () используются для аргументов всех функций.Но в OCAML () - это специальный символ, который обозначает «пустое значение», и у этого значения есть специальный тип, называемый «единицей».

Совершенно другое происходит, когда вы определяете q:Строка «abc» печатается сразу, поскольку это побочный эффект при оценке «print_string», и q становится равным (), поскольку () является результирующим значением, полученным путем оценки «print_string».*

0 голосов
/ 25 февраля 2013

Я опоздал на вечеринку, но хочу отметить, что использование () в

let p5 () = print_int 5

Имеет сопоставление с шаблоном в аргументе p5.Это эквивалентно этому:

let p5 x = match x with () -> print_int 5

Или это:

let p5 = function () -> print_int 5

Или даже это:

let p5 = fun x -> match x with () -> print_int 5

Это различие важно в следующем коде:

let f (x, y) = print_int (x + y)
let g x y = print_int (x + y)

f принимает только один параметр (пара (x, y)), а g получает два параметра.Таким образом, f имеет тип (int * int) -> unit, а g имеет тип int -> int -> unit.Так что f можно записать так:

let f pair = match pair with (x, y) -> print_int (x + y)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...