使用 OCaml GADT 编写解释器

2023-12-19

我正在用 OCaml 编写一个小型解释器,并使用 GADT 来输入我的表达式:

type _ value =
    | Bool : bool -> bool value
    | Int : int -> int value
    | Symbol : string -> string value
    | Nil : unit value
    | Pair : 'a value * 'b value -> ('a * 'b) value
and _ exp =
    | Literal : 'a value -> 'a exp
    | Var : name -> 'a exp
    | If : bool exp * 'a exp * 'a exp -> 'a exp
and name = string

exception NotFound of string

type 'a env = (name * 'a) list
let bind (n, v, e) = (n, v)::e
let rec lookup = function
    | (n, []) -> raise (NotFound n)
    | (n, (n', v)::e') -> if n=n' then v else lookup (n, e')

let rec eval : type a. a exp -> a value env -> a value = fun e rho ->
    match e with
    | Literal v -> v
    | Var n -> lookup (n, rho)
    | If (b, l, r) ->
            let Bool b' = eval b rho in
            if b' then eval l rho else eval r rho

但我无法编译我的代码。我收到以下错误:

File "gadt2.ml", line 33, characters 33-36:
Error: This expression has type a value env = (name * a value) list
       but an expression was expected of type
         bool value env = (name * bool value) list
       Type a is not compatible with type bool

我的理解是,由于某种原因rho正在被强迫进入一个bool value env,但我不知道为什么。我还尝试了以下方法:

let rec eval : 'a. 'a exp -> 'a value env -> 'a value = fun e rho ->
    match e with
    | Literal v -> v
    | Var n -> lookup (n, rho)
    | If (b, l, r) ->
            let Bool b = eval b rho in
            if b then eval l rho else eval r rho

但我不确定这到底有什么不同,而且它也给了我一个错误——尽管是一个不同的错误:

File "gadt2.ml", line 38, characters 56-247:
Error: This definition has type bool exp -> bool value env -> bool value
       which is less general than 'a. 'a exp -> 'a value env -> 'a value

GADT 指南,两者之间的差异evals,并且这个特殊问题都受到赞赏。干杯。


方式'a env旨在表示名称/值绑定的列表,但列表中的值必须都是相同的类型。两种不同的值类型(例如bool value and int value) 不是同一类型。如果eval b rho回报Bool b, rho必须是一个列表string * bool value. So eval l rho and eval r rho将返回bool value。但你的注释说函数返回a value.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 OCaml GADT 编写解释器 的相关文章

随机推荐