我不理解以下OCaml代码,因为我不确定 extract_ident 函数如何在没有明确指定它的情况下推断出一元参数 string_lexer 如何将其传递到提取。我知道你可以拥有一个没有匹配结构的函数,模式匹配中的类型是最后一个参数,但我不明白 string_lexer 参数是如何传递给隐式地提取?
type string_lexer = {string:string; mutable current:int; size:int } ;;
let init_lex s = {string=s, current=0; size=String.length s} ;;
let forward cl = cl.current <- cl.current+1 ;;
let forward_n cl n = cl.current <- cl.current+n ;;
let extract pred cl =
let st = cl.string and pos = cl.current in
let rec ext n = if n<cl.size && (pred st.[n]) then ext (n+1) else n in
let res = ext pos in
cl.current <- res; String.sub cl.string pos (res-pos) ;;
let extract_int =
let is_int = function '0'..'9' -> true | _ -> false
in function cl -> int_of_string (extract is_int cl);;
let extract_ident =
let is_alpha_num = function
'a'..'z' | 'A'..'Z' | '0'..'9' | '_' -> true
| _ -> false
in extract is_alpha_num ;;
答案 0 :(得分:1)
答案的第一部分是 currying 和部分申请。当你写
let f x y = ...
然后f x
是另一个参数(y
)的函数。
在您的示例中,OCaml可以推断extract_ident
的此参数的类型,因为它通过部分应用程序转发到extract
,并且该函数执行cl.string
和cl.current
它的cl
参数。记录标签唯一地确定相应的记录类型。 (如果具有相同标签的多个记录类型在范围内,则最后一个记录类型获胜,尽管最新的OCaml版本为与您的示例无关的案例添加了一些额外的智能。)