Well, my question does not meet the standards for a question at stackoverflow:
(I am a haskell beginner)
This example is from LYAH:
import System.Random
finiteRandoms :: (RandomGen g, Random a, Num n) => n -> g -> ([a], g)
finiteRandoms 0 gen = ([], gen)
finiteRandoms n gen =
let (value, newGen) = random gen
(restOfList, finalGen) = finiteRandoms (n-1) newGen
in (value:restOfList, finalGen)
Looking at that function, I find it impossible to understand how that recursion
works. I have to pull out a pencil and paper to figure it out. If I was given
the task of writing that function, I would write it like this:
import System.Random
finiteRands :: (RandomGen g, Random a) => Int -> g -> [a]
finiteRands n gen = finiteRands' n gen []
finiteRands' :: (RandomGen g, Random a) => Int -> g -> [a] -> [a]
finiteRands' 0 _ acc = acc
finiteRands' n gen acc =
let (rand_num, new_gen) = random gen
in finiteRands' (n-1) new_gen (rand_num:acc)
To me, it makes the function(s) simplistic to understand. Is the first
solution a known 'design pattern' in recursion? The first solution:
import System.Random
finiteRandoms :: (RandomGen g, Random a, Num n) => n -> g -> ([a], g)
finiteRandoms 0 gen = ([], gen)
finiteRandoms n gen =
let (value, newGen) = random gen
(restOfList, finalGen) = finiteRandoms (n-1) newGen
in (value:restOfList, finalGen)
seems to operate a bit like foldr: the recursion spins to the base case, and
the base case's return value, ([], gen), is passed back through all the
function calls. Each function call modifies the tuple (the in clause) before
returning it to the previous function call.
Is one solution more efficient than the other? I believe my solution is tail
recursive, but it's my understanding that compilers can now optimize just about
anything into tail recursion.
Thanks.
_______________________________________________
Haskell mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell