# Haskell Quiz/Internal Rate of Return/Solution Dolio

### From HaskellWiki

< Haskell Quiz | Internal Rate of Return(Difference between revisions)

(creation) |
(use until instead of iterate) |
||

(One intermediate revision by one user not shown) | |||

Line 1: | Line 1: | ||

+ | [[Category:Haskell Quiz solutions|Internal Rate of Return]] | ||

+ | |||

My solution for this quiz uses the [http://en.wikipedia.org/wiki/Secant_method secant method], which is quite easy to implement. | My solution for this quiz uses the [http://en.wikipedia.org/wiki/Secant_method secant method], which is quite easy to implement. | ||

Line 7: | Line 9: | ||

secant :: (Double -> Double) -> Double -> Double | secant :: (Double -> Double) -> Double -> Double | ||

− | secant f delta = fst | + | secant f delta = fst $ until err update (0,1) |

where | where | ||

update (x,y) = (x - (x - y)*(f x)/(f x - f y), x) | update (x,y) = (x - (x - y)*(f x)/(f x - f y), x) | ||

− | err (x,y) = abs (x - y) | + | err (x,y) = abs (x - y) < delta |

npv :: Double -> [Double] -> Double | npv :: Double -> [Double] -> Double |

## Latest revision as of 13:41, 9 February 2008

My solution for this quiz uses the secant method, which is quite easy to implement.

import Data.Function import Numeric import System.Environment secant :: (Double -> Double) -> Double -> Double secant f delta = fst $ until err update (0,1) where update (x,y) = (x - (x - y)*(f x)/(f x - f y), x) err (x,y) = abs (x - y) < delta npv :: Double -> [Double] -> Double npv i = sum . zipWith (\t c -> c / (1 + i)**t) [0..] main = do (s:t) <- getArgs let sig = read s cs = map read t putStrLn . ($"") . showFFloat (Just sig) $ secant (flip npv cs) (0.1^sig)

The resulting program expects the first argument to be the number of digits to be displayed after the decimal point, while the rest are the yearly income. For instance:

./IRR 4 -100 30 35 40 45 0.1709