OCaml 抽象数据类型中的匹配元素

Matching element in abstract data type in OCaml

我是 OCaml 的初学者。现在我正在练习我的一些代码。我刚刚测试了我的自定义数据类型(我不认为这真的是 'my' 自定义)但是我遇到了一个错误, 这是代码

type btree =
  | Empty
  | Node of (int * btree * btree)

let rec mem : int -> btree -> bool
= fun n t ->
  match t with
    |Empty -> false
    |Node (a,b,c) -> if a = n then true
                     else if mem n b then true
                     else if mem n c then true;;

OCaml 说最后一个 'true;应该是类型单元,但我计划这个 mem 函数应该 return 布尔值。我不明白为什么 'true' 不适合它... 顺便说一句,函数 mem 旨在检查 btree 't' 是否包含 int 'n'.

OCaml 有两种形式的 if 表达式:

if <cond> then <exp1> else <exp2>

if <cond> then <exp1>

在后一种形式中,else 分支被省略,默认为 else (),其中 () 是类型单元的值。也就是说,后一种形式是语法糖

if <cond> then <exp1> ::= if <cond> then <exp1> else ()

因此,当你写的时候,例如,

if friendly then "Say hello"

if friendly then "Say hello" else ()

此表达式格式不正确,因为根据条件 (friendly),它可能 return 类型为 string 的值或类型为 [=25 的值=].在 OCaml 中,每个表达式应该只有一种类型。

转到您的代码,特别是,您有一个 if/then/else 表达式链,最后一个 else 表达式被省略,可能是因为您认为它应该默认为 false (不是这种情况)。您的代码的语义正确版本是

if a = n then true
else if mem n b then true
else if mem n c then true
else false

但是,此代码可以改进。在 OCaml 中,(||)(&&) 运算符是短路的,即,在 x || y 中,如果 x 为真,则不会评估表达式 y。所以当我们有一个

形式的表达式时
 if <cond> then true else <bool-expr>

我们总是可以重写它更简洁(也更容易理解)

 <cond> || <bool-expr>

因此,您的代码可以重写为

a = n || mem n b || mem n c 

它简短得多,更容易理解,而且不容易出错。