
Tim Chevalier wrote:
On 11/5/07, Alex Young
wrote: randList :: Int -> [IO Int] randList n = randListTail [] n
randPairs :: Int -> [(IO Int, IO Int)] randPairs n = zip (randList n) (randList n) [snip] 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
It's unusual to return a list of IO actions or to take a list of pairs of IO actions as an argument. You should think about whether there's a reason you're doing this. For example, why not rewrite randList as:
randList :: Int -> IO [Int] randList n = sequence $ randListTail [] n
Wouldn't that force the list of Ints to be evaluated into memory all at once? I did have that (or a close approximation) in a previous version, but got rid of it because it wasn't clear to me how it could be lazily evaluated. The interesting thing about this specific problem (at least from my point of view) is that while random numbers happen in the IO monad, I explicitly don't care what order they are evaluated in - that's why I thought I'd be best off with a list of IO objects. Is this wrong?
(for example)?
piAsDouble :: Int -> Int -> Double piAsDouble a b = (fromInteger (toInteger a)) / (fromInteger (toInteger b))
This can be rewritten as: fromIntegral a / fromIntegral b (I think -- not tested. The above isn't tested either.)
Those are just a couple things that jump out at me. fSumListTail looks like it should be expressible using a foldM as well. I thought so, but couldn't quite figure it out. I'll have another stab at it.
(P.S. Sorry for the duplicate, Tim, I hadn't realised I replied off-list) Thanks, -- Alex