
On Sun, Dec 19, 2010 at 12:27 PM, ender
Hi all: I'v been learning haskell for several months, and now I'm trying to write some "real word" program in haskell, like finding files under one directory or something My problem is that, I dont know the way of writing a loop in haskell. I searched google and found some code that translate c loop into haskell like this one:
I am new to haskell and would look to write a function equivalent to the following loop in C
int value = 500000; int part_stack[4]; int *part_ptr = part_stack; for (; value; value /= 10000) *part_ptr++ = value % 10000;
part_stack :: [Int] part_stack = [0,50]
Note that I've performed a memoization optimization--this makes the code both smaller, faster and easier to read! :P
Ignore David, he's pulling your leg. Here's the proper translation:
do alloca $ \value -> do poke value (500000::Int) allocaArray 4 $ \part_stack -> do alloca $ \part_ptr -> do poke part_ptr part_stack let loop = do val <- peek value if val == 0 then return () else do p <- peek part_ptr poke p (val `rem` 10000) poke part_ptr (p `plusPtr` 1) poke value (val `quot` 10000) loop loop
and I really think that's not a "haskell way", it's just translate c code into haskell code byte by byte My question is: how to translate above c code into haskell in "haskell way"
Hi, Usually, loops are translated in recursion or higher order functions (maps, folds, scans). To generate a list from a number, use functions like iterate or repeat. To end the iterate, use a function from the takeWhile family. My translation of the above would be (no type signatures because I'm lazy right now): valueTrim x = div x 10000 valueGet x = mod x 100000 f x = map valueGet $ takeWhile (/= 0) $ iterate valueTrim x (call with f 500000) Reading the last line, you have a very concise description: trim x until it becomes 0 and apply valueGet to each of the results. -- Mihai