2010-04-30 4 views
9

Как я могу сделать эту функцию мощности Haskell рекурсивной?Как вы делаете эту функцию мощности Haskell рекурсивной?

turboPower a 0 = 1 
turboPower a b 
    | even b = turboPower (a*a) (b `div` 2) 
    | otherwise = a * turboPower a (b-1) 
+0

Вам не нужно '>' перед кодом. Просто отступьте его четырьмя пробелами. –

+0

Кстати, вы, вероятно, должны использовать 'quot' вместо' div'. Также обратите внимание, что обычный '(^)' также основан на алгоритме быстрого возведения в степень. – dfeuer

ответ

10
turboPower a b = turboPower' 1 a b 
    where 
    turboPower' x a 0 = x 
    turboPower' x a b 
     | x `seq` a `seq` b `seq` False = undefined 
     | even b = turboPower' x (a*a) (b `div` 2) 
     | otherwise = turboPower' (x*a) a (b-1) 

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

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

+0

Похоже, вы захотите сделать хвостовую рекурсивную версию строгой в аргументе аккумулятора. В противном случае ваш turboPower, вероятно, приведет к исчерпанию памяти, когда потребуется результат вычисления. –

+0

Хорошая точка - и я также хочу сделать ее строгой в 'a' тоже. Готово. –

 Смежные вопросы

  • Нет связанных вопросов^_^