
I'm working on learning arrows. This has led me to ArrowLoop, which then led me to trying to understand the following,
tracePlus b = let (c,d) = (d,b:d) in c
main = do w <- return $ take 10 $ tracePlus 7 print w
which yields [7,7,7,7,7,7,7,7,7,7] My confusion two pronged, 1) How let actually 'recurses' 2) How things get started (since d is undefined). I have some vague understanding of both issues but I want to make sure what's *really* going on so I don't base my Haskell learning experience on a house of cards. Help greatly appreciated. My ramblings 1) How does recursion happen? Being an ex-Schemer I recalled that let x = 3 get translated into something like (lambda (x) ... ) 3 So now there's a function involved. It's clear that b:d is (cons b d) another function. So with appropriate plumbing I could see the thing recurses but the Haskell viewpoint eludes me. 2) How do things get started? It seems that Haskell could figure out that 'd' is a list. If an uninitialized (undefined?) list contains [] then things are reasonably straightforward .. tracePlus gets applied to 7 (b:d) then becomes [7] (c,d) then becomes ([],7) Given there's an infinite loop (stream) then 'take' grabs 'c' (an []) and asks for another. Haskell's laziness works for us here. (b:d) then becomes [7,7] (c,d) then becomes (7,[7,7]) ... ... This is all fine. The only thing that subconsciously nags me is that we appear to 'return' each time which would imply that we would leave the closure causing 'd' to be undefined again. I know this isn't true and if I close my eyes, think really hard, and recall how streams are implemented in Scheme (with a value-promise pair; the closure is actually passed around) then I can see how this would all work. Back to the undefined list ... if it's *not* an [] and has something to do with bottom ( _|_ ) then my eyes glaze over and I have to go watch a Woody Allen movie to reset. Sorry for the rambling. I really like Haskell and I have found it very powerful. Any help greatly appreciated. Thanks, Tom