[Haskell] recursion patterns?
7stud
7stud at excite.com
Wed May 15 20:03:49 CEST 2013
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.
More information about the Haskell
mailing list