此表达式具有 bool 类型,但表达式应为 unit 类型,因为它是没有 else 分支的条件的结果

Posted

技术标签:

【中文标题】此表达式具有 bool 类型,但表达式应为 unit 类型,因为它是没有 else 分支的条件的结果【英文标题】:This expression has type bool but an expression was expected of type unit because it is in the result of a conditional with no else branch 【发布时间】:2022-01-08 16:52:03 【问题描述】:

感谢您阅读此问题。在我的 OCaml 代码中,我编写了一个函数来从我的 heap list 中检索最大的 object_

type object_ = int;;

let rec get_current_heap_max_object (heap1:heap) (acc:object_) = 
  match heap1 with 
  | [] -> acc 
  | hd :: tl -> 
    match hd with 
    | ((obj1, field1), tva1) -> 
      (if acc < obj1 then 
         acc = obj1; 
         get_current_heap_max_object tl acc 
       else 
         get_current_heap_max_object tl acc)

错误在acc = obj1; 为:

This expression has type bool but an expression was expected of type unit because it is in the result of a conditional with no else branch

【问题讨论】:

除了@octachron 发布的答案之外,OCaml 样式的注释:只有一种模式的match 是不必要的。您可能只是在第一个模式匹配中匹配了((obj1, field1), tva1) 模式。 | ((obj1, field1), tva1) :: tl -&gt; ... 这是对改进的建议,而不是批评。或者,如果是批评,建设性批评。消除不必要的代码通常会使代码更易于阅读和调试。此外,您甚至可以摆脱 if/else 并在您的模式匹配中使用 when 保护来简化您的代码。 好的!谢谢您的帮助。学习和遵循专业的编码行为对我有好处。 【参考方案1】:

在表达式中

if acc < obj1 then acc = obj1

子表达式acc = obj1 正在测试accobj1 的相等性,而不是为变量acc 赋值(变量在OCaml 中默认是不可变的)。由于then 分支返回一个布尔值,您不能省略else 分支。 您可以通过定义一个新的max 变量来重写代码以避免依赖可变性,该变量是accobj1

let max = if acc < obj1 then ... else ... in
get_current_heap_max_object tl max

【讨论】:

谢谢八时。我将代码修改为: let rec get_current_heap_max_object (heap1:heap) (acc:object_) = match heap1 with | []-> ACC | hd :: tl -> 匹配 hd 与 | ((obj1, field1),tva1) -> (let acc = if acc

以上是关于此表达式具有 bool 类型,但表达式应为 unit 类型,因为它是没有 else 分支的条件的结果的主要内容,如果未能解决你的问题,请参考以下文章

OCaml 断言失败

意外的类型名称“BOOL”:iOS SDK 6.1(设备)中的预期表达式

出现此异常:“DbSortClause 表达式必须具有顺序可比较的类型。参数名称:键”

类型“Null”不是类型转换中“bool”类型的子类型

使用类型表达式初始化 'void(^)(struct ALAssetsGroup *, BOOL *)' 的不兼容块指针类型

bool 函数用法