在模式匹配中使用 None 和 Some 会产生意想不到的结果

问题描述 投票:0回答:1

所以在我学习的课程中,我们尝试用 f# 编写一个解释器。为此我们必须制作一个小型计算器。 为此,我得到了这个代码:

type Value = INT of int

type Binop = BPLUS | BMINUS | BTIMES

type Rop = RSUM | RPROD | RMAX | RARGMAX

type vname = string

type Exp =
  | CONSTANT   of Value
  | VARIABLE   of vname
  | OPERATE    of Binop * Exp * Exp
  | LET_IN     of vname * Exp * Exp
  | OVER_LIST  of Rop * Exp list //must be non-empty
  | OVER_RANGE of Rop * vname * Exp * Exp * Exp

(* An association list mapping variable names to their values. *)
type SymTab = (vname * Value) list

(* Inserts a variable into the variable table. *)
let bind v k vtab = (v, k) :: vtab : SymTab

(* Look up the value of a variable. *)
let rec lookup v = function
  | (v', k) :: vtab -> if v = v' then k else lookup v vtab
  | _ -> failwith ("unbound variable: " + v)

(* EVALUATION *)

(*****************************************************
 * TODO: Task 2: complete the definition of `eval`. You may also
 * define any auxiliary functions as you see fit, to help express `eval`
 * as cleanly and concisely as possible.
 ****************************************************)

(* The evaluation function. *)
let rec eval (vtab : SymTab) (e : Exp) : Value =
  match e with
    | CONSTANT n -> n
    | VARIABLE v -> failwith "case for VARIABLE not handled"

我们必须自己定义变量和一些其他函数。

对于变量,我的想法是使用模式匹配,就像他们在讲座中所做的那样。

所以像这样

| VARIABLE v -> 
      match lookup v vtab with
      | Some x -> x
      | None -> failwith "Unknown variable."

因此,如果查找给出一个变量,我只返回该变量,如果没有,我返回一个错误,说它不存在。

但是当我这样做时我得到 “这个表达式的预期类型是 ‘价值’
但这里有类型 ‘‘一个选项’”

请不要只写出解决方案,但如果您能给出一些关于为什么这不起作用的提示,我会非常高兴。

types compiler-errors f#
1个回答
0
投票

据我了解您的代码,

vtab
是一个由元组列表(将变量与值映射)表示的符号表。您的
lookup
函数搜索符号表以查看是否找到给定变量,如果找到,则返回其值(类型为
Value
)。如果没有,您的代码将引发异常。稍后,在您的代码中,您期望使用
option<Value>
类型,正如 @Gus 指出的那样。

当找不到变量时,您不应在

lookup
中抛出异常,而应该返回
None
,以便它符合函数式风格以及您管理模式的想法
VARIABLE
。因此,我鼓励您修改代码以免引发异常。

例如,

let rec lookup v = function
  | (v', k) :: vtab -> if v = v' then Some k else lookup v vtab
  | _ -> None

如果您有权使用,您还应该使用已经可以实现您想要的功能的数据类型(例如Map)。

© www.soinside.com 2019 - 2024. All rights reserved.