OCaml - Tail Recursion для преобразования массива в список - PullRequest
0 голосов
/ 08 октября 2018

Я хочу написать функцию с хвостовой рекурсивной вспомогательной функцией для преобразования массива в список.

Пример:

#arraytolist  [|"a";"b"|];;
- :string list = ["a";"b"]
#arraytolist  [||];;
- :'alist = []

Вот мой код:

let arraytolist arr = 
    let rec helper alist index = 
        if arr = [||] then []
        else helper (arr.(index))::(List.tl alist) index+1
    in helper [] 0;;

Error: This expression has type int -> 'a list
       but an expression was expected of type 'a
       The type variable 'a occurs inside int -> 'a list

1 Ответ

0 голосов
/ 08 октября 2018

Есть несколько проблем с вашим кодом.

Первая и наиболее насущная проблема заключается в том, что вы неправильно заключаете в скобки аргументы рекурсивного вызова helper.Если вы сомневаетесь, вы должны поставить весь аргумент в скобках.Я думаю, что в настоящее время он анализирует это так: (helper arr.(index)) :: (((List.tl alist) index) + 1).

Во-вторых, ваш базовый случай равен arr = [||], когда arr никогда не меняется.Так что это будет верно, только если arr изначально пусто, в противном случае рекурсия не завершится.Если, конечно, index выходит за пределы и вызывает сбой программы, что произойдет, поскольку вы ее не проверяете.

Третья проблема заключается в том, что ваша функция всегда будет возвращать пустой список, посколькучто вы возвращаете в базовом случае (если его состояние было правильным).Все остальное, что вы сделали, просто отбрасывается.Есть способ написать вашу функцию, где имеет смысл возвращать пустой список в качестве базового варианта, и кажется, что вы наполовину пытаетесь это сделать, но такой подход не будет хвостовым рекурсивным.Вы захотите, чтобы рекурсивный вызов был последней операцией каждой итерации, а не операцией «против» результата рекурсивного вызова.

И четвертая проблема заключается в том, что вы отбрасываете заголовок alist на каждой итерации, используя List.tl, что не удастся на первой итерации, поскольку alist изначально пусто.И если бы это было не так, alist содержал бы только последний обработанный элемент.

Надеюсь, это даст вам достаточно времени, чтобы разобраться с этим.Основная идея кажется хорошей;вам просто нужно отсеять ошибки.

...