2010-04-30 7 views
9

Come potrei rendere ricorsiva questa funzione di potenza Haskell?Come si fa a rendere ricorsiva questa funzione di potenza Haskell?

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

Non è necessario '>' davanti al codice. Basta indentarlo di quattro spazi. –

+0

A proposito, dovresti probabilmente usare "quot" invece di "div". Inoltre, si noti che il solito '(^)' si basa anche su un algoritmo di esponenziazione veloce. – dfeuer

risposta

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) 

Fondamentalmente, ciò che si vuole fare è spostare la moltiplicazione che si sta facendo nel "otherwise" passo (dato che questo è ciò che mantiene questo dall'essere ricorsiva in coda inizialmente) ad un altro parametro.

Modificato per aggiungere una linea che valuti rigorosamente tutti e tre i parametri, anziché i pigri, poiché questa è una di quelle situazioni note in cui la pigrizia può farci del male.

+0

Sembra che vorrai rendere rigorosa la versione ricorsiva della coda nell'argomento dell'accumulatore. In caso contrario, il tuo turboPower causerà probabilmente esaurimento della memoria quando viene richiesto il risultato del calcolo. –

+0

Buon punto - e anch'io voglio renderlo rigoroso anche in 'a'. Fatto. –