Пожалуйста, как мне сделать эту функцию Tail-рекурсивной в F #? - PullRequest
0 голосов
/ 12 ноября 2018

let ListtoTuple (lst: 'a list) :(' a * 'a) list =

let rec loop (lt :'a list) acc =
    match lt with         
    | x:: y :: t-> (x,y):: loop  t acc 
    |   _   -> acc
loop lst []

Вопрос: ListtoTuple 6 [1..1000000]

Я хочу получить такой результат: [(1, 2); (3, 4); (5, 6); (7, 8); (9, 10) ...] но я продолжаю получать процесс прекращается из-за StackOverflow. Пожалуйста, я хотел бы знать, если я что-то не так делаю.

Ответы [ 2 ]

0 голосов
/ 12 ноября 2018

Ваш код почти правильный.Проблема здесь:

(x,y):: loop f t acc

Вы объединяетесь с результатом loop, что означает, что он не является хвостовой рекурсией, потому что он должен ждать, пока результат loop затем объединится.

Ключ находится в параметре acc, который обозначает аккумулятор.Это означает, что вам нужно конкатенировать ваш результирующий список, который затем передается на следующий уровень, пока больше нечего добавить, и тогда acc имеет заполненный список, который возвращается сюда:

|   _   -> acc
0 голосов
/ 12 ноября 2018

От этой темы :

let listToPairList lst =
    let rec aux acc lst = 
        match lst with
        | []         -> acc |> List.rev
        | x::[]      -> (x,x)::acc |> List.rev
        | x1::x2::xs -> aux ((x1,x2)::acc) xs
    aux [] lst
...