尾递归错误:表达式的类型为int,但是期望表达式的类型为unit

时间:2019-01-17 22:36:30

标签: ocaml

我刚开始在学校的一门课程中使用OCaml功能编程语言进行编程。我们的问题之一是编写所谓的“俄罗斯农民算法”,但使用尾部递归而不是常规递归。我想我已经快知道了,但是我一直遇到一个愚蠢的错误,我似乎无法指出。 “此表达式的类型为int,但应为类型的表达式          “ aux x(base * base)(power / 2)”行上的“ unit”字样。由于我是该语言语法的新手,我真的不确定如何解决此问题。有什么想法吗?

我认为这是由没有分支的条件引起的;但是我已经实现了这一点,所以对于为什么它不起作用我感到很困惑。

<div id="DocumentManager"
    [attr.data-title]="title"
    [attr.data-startingCategory]="startingCategory"
    [attr.data-orgId]="orgId"
    [attr.data-isAdmin]="isAdmin" > 
</div>

该函数的目标是例如调用exp_program(2,3)并使其产生base ^ power。在这种情况下,它将导致8

2 个答案:

答案 0 :(得分:3)

您缺少else子句。

解决方案:删除最后一个else if并替换为else

let exp_program (base, power) = 
  let rec func x base power =
    if base = 0 then 0
    else if power = 0 then x
    else if power = 1 then x*base
    else if (odd power) then
      func (x*base) (base*base) ((power-1)/2)
    else 
      func x (base*base) (power/2)
in  
func 1 base power ;;

答案 1 :(得分:0)

构造

if <boolean> then <expression>

带有隐式

else ()

您的if阶梯中的最后一个if ... else if ... else if ... else if就是这样的构造,因此具有隐式else ()。类型推断类型向后工作,因此首先看到()的隐式返回,并将单元推断为if的返回类型。尽管then分支的类型为int,所以您得到了所描述的错误。

解决此问题的最简单方法是仅用else if替换最后一个else。这也节省了时间,因为您知道力量并不奇怪。