好的,我想我可能明白你的问题。以函数开头的数据结构就是函数!在 OCaml 中,函数是第一类对象,您可以创建新的对象,将它们保存在数据结构中,等等。为了使事情保持纯粹,您无法访问函数的文本表示(就像在某些语言中一样),但您仍然可以以有用的方式组合函数。
这是一个小例子。该函数maketest
接受一个值k
并返回一个测试k
.
# let maketest k = fun x -> x = k;;
val maketest : 'a -> 'a -> bool = <fun>
# let t8 = maketest 8;;
val t8 : int -> bool = <fun>
# t8 3;;
- : bool = false
# t8 8;;
- : bool = true
该函数union
接受两个测试函数(如由 生成maketest
的函数)并返回一个测试两组值的并集的函数:
# let union f g = fun x -> f x || g x;;
val union : ('a -> bool) -> ('a -> bool) -> 'a -> bool = <fun>
# let t812 = union t8 (maketest 12);;
val t812 : int -> bool = <fun>
# t812 8;;
- : bool = true
# t812 12;;
- : bool = true
# t812 14;;
- : bool = false
#
该函数sequence
采用两个测试函数(如由 生成的那些maketest
)并测试以依次匹配两个函数的整数开头的列表。
# let sequence f g = function
| []|[_] -> false
| a :: b :: _ -> f a && g b;;
val sequence : ('a -> bool) -> ('a -> bool) -> 'a list -> bool = <fun>
# sequence (maketest 1) (maketest 4) [1;4;7];;
- : bool = true
# sequence (maketest 1) (maketest 4) [1;8;7];;
- : bool = false
#
我不完全确定,但我认为您被要求为您的语法组件创建类似于这些的函数。要从这样的函数制作解析器,您需要通过输入流跟踪您的进度。通常的方法是让解析函数返回剩余的(未解析的)流。