Alex Young wrote:
rand :: IO Int
rand = getStdRandom (randomR (0, randMax))
randListTail accum 0 = accum
randListTail accum n = randListTail (rand : accum) (n - 1)
randList :: Int -> [IO Int]
randList n = randListTail [] n
randPairs :: Int -> [(IO Int, IO Int)]
randPairs n = zip (randList n) (randList n)
This looks entirely broken. How about this?
randList :: Int -> IO [Int]
randList n = mapM (\x -> randomRIO (0, randMax)) [1..n]
(Sorry, I'm not very familiar with the Random module. However, I believe
this works.) This then gives you an ordinary list of integers, which
elides some of the stuff below...
pairIsInside x y = if x*x + y*y < unitRadius then 1 else 0
This is fairly atypical in Haskell. More likely you'd do something like
pairIsInside :: (Int,Int) -> Bool
pairIsInside x y = x*x + y*y < unitRadius
and then later write
length . filter pairIsInside
instead of using "sum".
doCountPair :: (IO Int, IO Int) -> IO Int
doCountPair (a, b) = do
x <- a
y <- b
return (pairIsInside x y)
fSumListTail :: Int -> [(IO Int, IO Int)] -> IO Int
fSumListTail total [] = do
return total
fSumListTail total (x:xs) = do
y <- doCountPair x
fSumListTail (total+y) xs
fSumList :: [(IO Int, IO Int)] -> IO Int
fSumList l = fSumListTail 0 l
Most of this goes away if you use an "IO [Int]" rather than "[IO Int]".
piAsDouble :: Int -> Int -> Double
piAsDouble a b =
(fromInteger (toInteger a)) / (fromInteger (toInteger b))
I don't *think* you need the toInteger there - I may be wrong...
calculatePi total = do
count <- fSumList (randPairs total)
return (piAsDouble (4*count) total)
This looks OK.
main = do
args <- getArgs
(calculatePi (read (args !! 0))) >>= (putStr . show)
This looks OK too - if a little confusing. As a matter of style, I'd write
main = do
args <- getArgs
case args of
[size] -> print $ calculatePi $ read size
_ -> putStrLn "Usage: CALCPI <size>"
But that's just me...
_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe