Ошибка рекурсии хвоста: выражение имеет тип int, но ожидалось выражение типа unit - PullRequest
0 голосов
/ 18 января 2019

Я только начал программировать на функциональном языке программирования OCaml для одного из моих классов в школе. Одна из наших проблем состояла в том, чтобы написать так называемый «русский крестьянский алгоритм», но с использованием хвостовой рекурсии вместо обычной рекурсии. Я думаю, что я почти получил это, но я продолжаю сталкиваться с глупой ошибкой, которую я не могу точно определить; «Это выражение имеет тип int, но ожидалось выражение типа unit "over the line" aux x (base * base) (power / 2) ". Я действительно не уверен, как это исправить, поскольку я новичок в синтаксисе языка. Любые идеи?

Я полагаю, что это вызвано условием без ветвления; однако я реализовал это, поэтому я совершенно не понимаю, почему это не работает.

let even n = (n mod 2) = 0 ;;
let odd n = (n mod 2) = 1;; 

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 if (even power) then 
      func x (base*base) (power/2)
in  
func 1 base power ;;

Цель этой функции - вызвать, например, exp_program (2, 3) и получить базовую мощность. В этом случае это приведет к 8

Ответы [ 2 ]

0 голосов
/ 21 января 2019

Конструкция

if <boolean> then <expression>

поставляется с неявным

else ()

Последняя if в вашей if ... else if ... else if ... else if лестнице является такой конструкцией и поэтому имеет неявную else (). Тип вывода типа работает в обратном направлении, поэтому неявный возврат () виден первым, а unit выводится как тип возврата if. Ветвь then имеет тип int, поэтому вы получите сообщение об ошибке, которую вы описали.

Самый простой способ исправить это - заменить последний else if просто else. Это также экономит время, поскольку вы знаете, что сила должна быть четной, поскольку она не странная.

0 голосов
/ 18 января 2019

Вы пропустили предложение 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 ;;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...