F # stackoverflow project euler # 4

Я работаю над проблемой четырех Project Euler и запускаю исключение stackoverflow. Я не прошу помощи в решении проблемы, я просто хотел бы объяснить, почему я получаю исключение stackoverflow. Это обычно из-за бесконечной рекурсии, но я не верю, что это так на этот раз (если я просто слепой и не вижу его прямо сейчас, дайте мне знать).

Здесь код:

let Euler4 =

let reverse sum =
    let rec loop (n,x) =
        if n = 0
        then
            x
        else
            loop (n/10,(x*10) + (n%10))

    loop (sum, 0);

let isPalindrome arg = (arg = (reverse arg));

let findPalindromes (startx,starty) =
    let rec loop (x,y) acc =
        let result = if isPalindrome (x * y) then ((x,y) :: acc) else acc;
        let next = match (x,y) with
            | (x,y) when y = 100 -> (x-1,starty)
            | _ -> (x,y-1)
        if x = 100 then
            result
        else
            loop (next) result

    loop (startx,starty) [];


let value = (999,999);
printfn "%A" (findPalindromes value);

;

Ответы

Ответ 1

Собираетесь ли вы в режиме "Отладка" или "Выпуск"? Режим отладки в VS имеет хвостовые звонки, отключенные по умолчанию (флаг компилятора "-tailcalls-" ), чтобы сохранить стеки для отладки, но у этого есть компромисс, который вы можете использовать StackOverflow. Вы можете переключиться в режим "Release", или

  • щелкните правой кнопкой мыши свойства проекта в обозревателе решений, выберите "Свойства"
  • перейдите на вкладку "Создать"
  • убедитесь, что выбрана конфигурация "Отладка"
  • щелкните поле "Генерировать хвостовые вызовы"

для включения хвостовых вызовов с настройками "Отладка" .

(Ваша программа работает нормально для меня с включенными разрешениями на звонки.)

Ответ 2

Я не могу читать F # и не знаю, связана ли ваша проблема с этим, но особенно если вы что-то рекурсивно пытаетесь избежать проверки равенства на число, вместо этого попробуйте проверить порог. Например, вместо проверки n = 0 тест n <= 0.