如何从类型Ocaml中提取值

如何从类型Ocaml中提取值,ocaml,Ocaml,我有一种 type expr = Const of int | Var of string | Bin of expr * binop * expr 也 及 Binop在两个expr上执行一个操作,我需要编写一个eval函数,该函数接受闭包和expr并返回一个值 前 我遇到的问题是函数需要返回INT而不是实际的into值 这就是我到目前为止写的 let rec eval (evn,e) = match e with | Const a -> Int a | Var x-

我有一种

type expr =   
Const of int 
| Var of string    
| Bin of expr * binop * expr 

Binop在两个expr上执行一个操作,我需要编写一个eval函数,该函数接受闭包和expr并返回一个值

我遇到的问题是函数需要返回INT而不是实际的into值

这就是我到目前为止写的

let rec eval (evn,e) = match e with
| Const a -> Int a
| Var x-> Int (lookup (x,evn) )
| Bin( Var x, Plus, Var y) ->   Int ( eval(evn,Var x) + eval(evn,Var y) )
| Bin( Var x, Minus, Var y) -> Int ( eval(evn,Var x) + eval(evn,Var y) )
| Bin( Var x, Mul, Var y) ->   Int ( eval(evn,Var x) + eval(evn,Var y) )
| Bin( Var x, Div, Var y) ->  Int ( eval(evn,Var x) + eval(evn,Var y) )

;;
查找在闭包evn中查找x并返回其值
我遇到的问题是,我需要在bin匹配中执行整数运算,但由于eval返回值的类型,我不能这样做。如何更改最后四个匹配项中的代码,使其能够执行算术运算并在完成后返回Int的Int类型?

您需要

let x =
  match eval (evn, Var x) with
  | Int x -> x
  | _ -> failwith "runtime error"
in

let y =
  match eval (evn, Var y) with
  | Int y -> y
  | _ -> failwith "runtime error"
in

Int (x + y)
在每个匹配案例中。您可能应该将此模式匹配分解为一个可以重复调用的函数:

let get_int = function
  | Int i -> i
  | _ -> failwith "runtime error: expected an integer"

... Int ((eval (evn, e1) |> get_int) + (eval (evn, e2) |> get_int))
您必须在计算器中执行此运行时检查,这应该是有意义的–在您的表示中,没有理由不将变量映射到
evn
中的闭包,而不是整数

还要注意,与您的问题相反,
evn
本身并不是一个闭包。它通常被称为“环境”。闭包是由闭包构造的值,它们承载着环境,还有其他东西——不过,我认为您只是输入了一个错误


当然,我假设您将来会将
Var x
Var y
概括为
e
e'

此外,我不禁想知道“
evn
”是否不应该是“
env
”。使用一个助手函数使其工作,该函数接受EXPR并将其转换为INT,然后执行操作,然后返回EXPR
let rec eval (evn,e) = match e with
| Const a -> Int a
| Var x-> Int (lookup (x,evn) )
| Bin(  el, Plus,  er) ->
    let Int cl=eval (evn,el ) and Int cr=eval (evn,er ) in
    Int (cl+cr)
| Bin(  el, Minus,  er) ->
    let Int cl=eval (evn,el ) and Int cr=eval (evn,er ) in
    Int (cl-cr)
| Bin(  el, Mul,  er) ->
    let Int cl=eval (evn,el ) and Int cr=eval (evn,er ) in
    Int (cl*cr)
| Bin(  el, Div,  er) ->
    let Int cl=eval (evn,el ) and Int cr=eval (evn,er ) in
    Int (cl/cr)
let x =
  match eval (evn, Var x) with
  | Int x -> x
  | _ -> failwith "runtime error"
in

let y =
  match eval (evn, Var y) with
  | Int y -> y
  | _ -> failwith "runtime error"
in

Int (x + y)
let get_int = function
  | Int i -> i
  | _ -> failwith "runtime error: expected an integer"

... Int ((eval (evn, e1) |> get_int) + (eval (evn, e2) |> get_int))
let rec eval (evn,e) = match e with
| Const a -> Int a
| Var x-> Int (lookup (x,evn) )
| Bin(  el, Plus,  er) ->
    let Int cl=eval (evn,el ) and Int cr=eval (evn,er ) in
    Int (cl+cr)
| Bin(  el, Minus,  er) ->
    let Int cl=eval (evn,el ) and Int cr=eval (evn,er ) in
    Int (cl-cr)
| Bin(  el, Mul,  er) ->
    let Int cl=eval (evn,el ) and Int cr=eval (evn,er ) in
    Int (cl*cr)
| Bin(  el, Div,  er) ->
    let Int cl=eval (evn,el ) and Int cr=eval (evn,er ) in
    Int (cl/cr)