[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