Re: [Haskell-cafe] using the writer monad to better understand foldl and foldr, and haskell debugging techniques in general

same behavior with myfoldrD (:) [] [1..] -- uses Debug.Trace.trace So, I would say this proves my main point, which was that you could accomplish the same thing using the writer monad that you could do using the more "ad hoc" trace function from Debug.Trace. It's good that you point this out though, because understanding that foldr can take an infinite list and foldl not is a very key point.
2008/2/10, Felipe Lessa
: On Feb 10, 2008 9:33 PM, Thomas Hartman
wrote: -- using writer monad -- Nothing unsafe here, pure referrentially transparent goodness myfoldrW f z [] = return z myfoldrW f z (x:xs) = do r <- (myfoldrW f z xs) tell ("x,r: " ++ (show (x,r)) ++ "\n" ) return $ x `f` r
*Main> foldr const 0 [1..] 1 *Main> putStrLn $ snd $ runWriter $ myfoldrW const 0 [1..] Interrupted.
One of the good things from foldr is the possibility of "short-circuiting", so to speak. However I don't know if it is possible to show this using the writer monad, as is would involve observing if the function is strict or not in its second argument.
Cheers,
-- Felipe.

On Feb 10, 2008 9:52 PM, Thomas Hartman
So, I would say this proves my main point, which was that you could accomplish the same thing using the writer monad that you could do using the more "ad hoc" trace function from Debug.Trace.
Not really. That only happens with your implementation of myfoldrD. If you write it as myfoldrD' f z [] = z myfoldrD' f z (x:xs) = x `f` trace ("x,r: " ++ (show (x,r))) r where r = myfoldrD' f z xs then we have the expected behavior *Main> myfoldrD (:) [] [1..5] x,r: (5,[]) x,r: (4,[5]) x,r: (3,[4,5]) x,r: (2,[3,4,5]) x,r: (1,[2,3,4,5]) [1,2,3,4,5] *Main> myfoldrD' (:) [] [1..5] [1x,r: (5,[]) x,r: (4,[5]) x,r: (3,[4,5]) x,r: (2,[3,4,5]) x,r: (1,[2,3,4,5]) ,2,3,4,5] *Main> myfoldrD const 0 [1..] Interrupted. *Main> myfoldrD' const 0 [1..] 1 *Main> myfoldrD (\x xs -> if x < 0 then [] else x:xs) [] ([1,2,3,-1] ++ repeat 0) *** Exception: stack overflow *Main> myfoldrD' (\x xs -> if x < 0 then [] else x:xs) [] ([1,2,3,-1] ++ repeat 0) [1x,r: (3,[]) x,r: (2,[3]) x,r: (1,[2,3]) ,2,3] As Debug.Trace hides the IO monad in a pure computation (i.e. unsafePerformIO) we can use it from the inside of the [pure] function that is passed to foldr. Note that we could also implement a Writer monad on top of unsafePerformIO, you basically just change Debug.Trace to an IO action that does the mappend as Writer would but in an IORef. In the end you read that IORef and do a big tell to the outside Writer monad. I'd say that this is a safe use of unsafePerformIO as it shouldn't break referential transparency. But without this hack I don't think we could do the same thing. Good news is that the hack is 'hideable' as are the hacks from ByteString, for example. Cheers, -- Felipe.

On Feb 11, 2008 7:53 AM, Felipe Lessa
read that IORef and do a big tell to the outside Writer monad. I'd say that this is a safe use of unsafePerformIO as it shouldn't break referential transparency. But without this hack I don't think we could
Well, not really as well. The IO action from unsafePerformIO may be executed several times, I guess. =) -- Felipe.
participants (2)
-
Felipe Lessa
-
Thomas Hartman