Синтаксическая ошибка OCaml в общем операторе с объявлением модуля - PullRequest
0 голосов
/ 15 февраля 2020
  1 module type Dictionary = sig
  2     type ('k, 'v) t
  3
  4     val empty : ('k, 'v) t
  5     val insert : 'k -> 'v -> ('k, 'v) t -> ('k, 'v) t
  6     val lookup : 'k -> ('k, 'v) t -> 'v
  7 end
  8
  9 module DictionaryImpl : Dictionary = struct
 10     type ('k, 'v) t = ('k * 'v) list
 11     let empty = []
 12     let insert k v t = (k,v)::t
 13     (*let lookup k t = List.assoc k t*)
 14     let rec lookup k t =
 15         match t with
 16         | [] -> failwith "No data"
 17         | hd::tl ->
 18                if fst hd = k then snd hd
 19                else lookup k tl
 20 end
 21
 22 let _ =
 23     let a = DictionaryImpl.empty in
 24     let b = DictionaryImpl.insert "first" 1 a in
 25     DictionaryImpl.lookup "first" b
 26

Пожалуйста, обратите внимание на строки между 22 и 25.
Если я изменяю следующий код, возникает синтаксическая ошибка, но я не знаю, почему.

let a = DictionaryImpl.empty in
let b = DictionaryImpl.insert "first" 1 a in
DictionaryImpl.lookup "first" b

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

1 Ответ

1 голос
/ 16 февраля 2020

Разница в том, что

let _ =
  let a = DictionaryImpl.empty in
  let b = DictionaryImpl.insert "first" 1 a in
  DictionaryImpl.lookup "first" b

является определением (даже если это определение не связывает никакие переменные). Наоборот

let a = DictionaryImpl.empty in
let b = DictionaryImpl.insert "first" 1 a in
DictionaryImpl.lookup "first" b

это выражение. Высокоуровневые выражения необходимо отделить от определений ;;:

;; 
let a = DictionaryImpl.empty in
let b = DictionaryImpl.insert "first" 1 a in
DictionaryImpl.lookup "first" b

Однако эта форма не полностью идиоматична c, и многие люди предпочитают предвосхищать определения go, чтобы использовать только определения. Например, можно написать

let location="universe"
let () = Format.printf "Hello, %s" location

вместо

let location="universe"
;;
Format.printf "Hello, %s" location
...