Is traceIO unnecessarily specialised to the IO monad?
I use printf-style debugging a lot, so I am always adding and removing applications of trace. There is the Debug.Trace.traceIO function that makes this easy to do in the IO monad (it just applies hPutStrLn stderr), but is that specialisation to IO unnecessary? I find myself always using this utility function: traceM :: (Monad m) => String -> m () traceM message = trace message $ return () Which can be used to implement traceIO. traceIO :: String -> IO () traceIO = traceM That way I can traceM in whatever monad I am in. It is easier to add and remove an application of trace, because I do not have to wrap it around something, and I do not have to remember the return. Of course, you are still subject to however your monad chooses to order the execution of these traces, but that is what people expect when using trace. Would traceM be a wanted addition to Debug.Trace? Regards, Chris Seaton
The user can generate the string however they want. The proposed traceM does not duplicate any printf functionality, and neither requires nor prevents the use of printf. It is more about allowing the user to add trace actions in an arbitrary monad, rather than just the IO monad. If people want to trace in IO, and we think it is worth a function to do that, might they not want to trace in any monad, and it be worth adding a function for that? Chris On 21 January 2013 16:53, Henning Thielemann <lemming@henning-thielemann.de>wrote:
On Mon, 21 Jan 2013, Chris Seaton wrote:
Would traceM be a wanted addition to Debug.Trace?
You can use printf for generating Strings and show them using plain 'trace'.
Chris Seaton <chris@chrisseaton.com> writes:
I use printf-style debugging a lot, so I am always adding and removing applications of trace. There is the Debug.Trace.traceIO function that makes this easy to do in the IO monad (it just applies hPutStrLn stderr), but is that specialisation to IO unnecessary?
I find myself always using this utility function:
traceM :: (Monad m) => String -> m () traceM message = trace message $ return ()
Which can be used to implement traceIO.
traceIO :: String -> IO () traceIO = traceM
btw, that wouldn't have the same semantics as the existing `Debug.Trace.traceIO` which is more or less something similiar to a `hPutStrLn stderr` whose side-effect gets triggered at monad-execution time, whereas the side-effect of `traceM` occurs at monad-construction time; consider the following program: --8<---------------cut here---------------start------------->8--- import Control.Monad import Debug.Trace traceM :: (Monad m) => String -> m () traceM message = trace message $ return () traceIO' :: String -> IO () traceIO' = traceM main = replicateM_ 5 $ do trace1 trace2 where trace1 = traceIO' "trace1" trace2 = traceIO "trace2" --8<---------------cut here---------------end--------------->8--- when run via runghc (or compiled with -O0) for GHC 7.6, this emits --8<---------------cut here---------------start------------->8--- trace1 trace2 trace2 trace2 trace2 trace2 --8<---------------cut here---------------end--------------->8--- only when using -O1 or -O2 the output results in --8<---------------cut here---------------start------------->8--- trace1 trace2 trace1 trace2 trace1 trace2 trace1 trace2 trace1 trace2 --8<---------------cut here---------------end--------------->8--- (I'm guessing this due to `trace1` being inlined for -O1/-O2 -- but I haven't checked) cheers, hvr
Yes, I suppose that traceIO does not have the semantics I assumed. Still, I think it is useful to have a trace that one can easily insert into an arbitrary monad. Here's how I use it: -------- import Debug.Trace main :: IO () main = putStrLn $ show foo foo :: Maybe Int foo = do x <- bar 14 traceM $ show x y <- bar 2 traceM $ show y return $ x + y bar :: Int -> Maybe Int bar x = Just $ 2*x traceM :: (Monad m) => String -> m () traceM message = trace message $ return () ---------- I think it is cleaner and more obvious than without the abstraction. Plus it is very easy to comment out. It is really good for list comprehensions written in do notation, as I often want to peek at intermediate values of those. I know I always add it to my projects, so I thought it may be wanted in base. As Henning Thielemann said, you can use printf or whatever with it, but I think that is an orthogonal issue. Regards, Chris On 21 January 2013 17:09, Herbert Valerio Riedel <hvr@gnu.org> wrote:
Chris Seaton <chris@chrisseaton.com> writes:
I use printf-style debugging a lot, so I am always adding and removing applications of trace. There is the Debug.Trace.traceIO function that makes this easy to do in the IO monad (it just applies hPutStrLn stderr), but is that specialisation to IO unnecessary?
I find myself always using this utility function:
traceM :: (Monad m) => String -> m () traceM message = trace message $ return ()
Which can be used to implement traceIO.
traceIO :: String -> IO () traceIO = traceM
btw, that wouldn't have the same semantics as the existing `Debug.Trace.traceIO` which is more or less something similiar to a `hPutStrLn stderr` whose side-effect gets triggered at monad-execution time, whereas the side-effect of `traceM` occurs at monad-construction time; consider the following program:
--8<---------------cut here---------------start------------->8--- import Control.Monad import Debug.Trace
traceM :: (Monad m) => String -> m () traceM message = trace message $ return ()
traceIO' :: String -> IO () traceIO' = traceM
main = replicateM_ 5 $ do trace1 trace2 where trace1 = traceIO' "trace1" trace2 = traceIO "trace2" --8<---------------cut here---------------end--------------->8---
when run via runghc (or compiled with -O0) for GHC 7.6, this emits
--8<---------------cut here---------------start------------->8--- trace1 trace2 trace2 trace2 trace2 trace2 --8<---------------cut here---------------end--------------->8---
only when using -O1 or -O2 the output results in
--8<---------------cut here---------------start------------->8--- trace1 trace2 trace1 trace2 trace1 trace2 trace1 trace2 trace1 trace2 --8<---------------cut here---------------end--------------->8---
(I'm guessing this due to `trace1` being inlined for -O1/-O2 -- but I haven't checked)
cheers, hvr
+1. I also had to define traceM for the same purposes. --Andreas On 21.01.13 6:41 PM, Chris Seaton wrote:
Yes, I suppose that traceIO does not have the semantics I assumed. Still, I think it is useful to have a trace that one can easily insert into an arbitrary monad. Here's how I use it:
--------
import Debug.Trace
main :: IO () main = putStrLn $ show foo
foo :: Maybe Int foo = do x <- bar 14 traceM $ show x y <- bar 2 traceM $ show y return $ x + y
bar :: Int -> Maybe Int bar x = Just $ 2*x
traceM :: (Monad m) => String -> m () traceM message = trace message $ return ()
----------
I think it is cleaner and more obvious than without the abstraction. Plus it is very easy to comment out. It is really good for list comprehensions written in do notation, as I often want to peek at intermediate values of those. I know I always add it to my projects, so I thought it may be wanted in base.
As Henning Thielemann said, you can use printf or whatever with it, but I think that is an orthogonal issue.
Regards,
Chris
On 21 January 2013 17:09, Herbert Valerio Riedel <hvr@gnu.org <mailto:hvr@gnu.org>> wrote:
Chris Seaton <chris@chrisseaton.com <mailto:chris@chrisseaton.com>> writes:
> I use printf-style debugging a lot, so I am always adding and removing > applications of trace. There is the Debug.Trace.traceIO function that makes > this easy to do in the IO monad (it just applies hPutStrLn stderr), but is > that specialisation to IO unnecessary? > > I find myself always using this utility function: > > traceM :: (Monad m) => String -> m () > traceM message = trace message $ return () > > Which can be used to implement traceIO. > > traceIO :: String -> IO () > traceIO = traceM
btw, that wouldn't have the same semantics as the existing `Debug.Trace.traceIO` which is more or less something similiar to a `hPutStrLn stderr` whose side-effect gets triggered at monad-execution time, whereas the side-effect of `traceM` occurs at monad-construction time; consider the following program:
--8<---------------cut here---------------start------------->8--- import Control.Monad import Debug.Trace
traceM :: (Monad m) => String -> m () traceM message = trace message $ return ()
traceIO' :: String -> IO () traceIO' = traceM
main = replicateM_ 5 $ do trace1 trace2 where trace1 = traceIO' "trace1" trace2 = traceIO "trace2" --8<---------------cut here---------------end--------------->8---
when run via runghc (or compiled with -O0) for GHC 7.6, this emits
--8<---------------cut here---------------start------------->8--- trace1 trace2 trace2 trace2 trace2 trace2 --8<---------------cut here---------------end--------------->8---
only when using -O1 or -O2 the output results in
--8<---------------cut here---------------start------------->8--- trace1 trace2 trace1 trace2 trace1 trace2 trace1 trace2 trace1 trace2 --8<---------------cut here---------------end--------------->8---
(I'm guessing this due to `trace1` being inlined for -O1/-O2 -- but I haven't checked)
cheers, hvr
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
-- Andreas Abel <>< Du bist der geliebte Mensch. Theoretical Computer Science, University of Munich Oettingenstr. 67, D-80538 Munich, GERMANY andreas.abel@ifi.lmu.de http://www2.tcs.ifi.lmu.de/~abel/
While we're at it, the trace functions I miss are \x -> trace x x and \x -> trace (show x) x Roman * Andreas Abel <andreas.abel@ifi.lmu.de> [2013-01-21 23:31:24+0100]
+1. I also had to define traceM for the same purposes. --Andreas
On 21.01.13 6:41 PM, Chris Seaton wrote:
Yes, I suppose that traceIO does not have the semantics I assumed. Still, I think it is useful to have a trace that one can easily insert into an arbitrary monad. Here's how I use it:
--------
import Debug.Trace
main :: IO () main = putStrLn $ show foo
foo :: Maybe Int foo = do x <- bar 14 traceM $ show x y <- bar 2 traceM $ show y return $ x + y
bar :: Int -> Maybe Int bar x = Just $ 2*x
traceM :: (Monad m) => String -> m () traceM message = trace message $ return ()
----------
I think it is cleaner and more obvious than without the abstraction. Plus it is very easy to comment out. It is really good for list comprehensions written in do notation, as I often want to peek at intermediate values of those. I know I always add it to my projects, so I thought it may be wanted in base.
As Henning Thielemann said, you can use printf or whatever with it, but I think that is an orthogonal issue.
Regards,
Chris
On 21 January 2013 17:09, Herbert Valerio Riedel <hvr@gnu.org <mailto:hvr@gnu.org>> wrote:
Chris Seaton <chris@chrisseaton.com <mailto:chris@chrisseaton.com>> writes:
> I use printf-style debugging a lot, so I am always adding and removing > applications of trace. There is the Debug.Trace.traceIO function that makes > this easy to do in the IO monad (it just applies hPutStrLn stderr), but is > that specialisation to IO unnecessary? > > I find myself always using this utility function: > > traceM :: (Monad m) => String -> m () > traceM message = trace message $ return () > > Which can be used to implement traceIO. > > traceIO :: String -> IO () > traceIO = traceM
btw, that wouldn't have the same semantics as the existing `Debug.Trace.traceIO` which is more or less something similiar to a `hPutStrLn stderr` whose side-effect gets triggered at monad-execution time, whereas the side-effect of `traceM` occurs at monad-construction time; consider the following program:
--8<---------------cut here---------------start------------->8--- import Control.Monad import Debug.Trace
traceM :: (Monad m) => String -> m () traceM message = trace message $ return ()
traceIO' :: String -> IO () traceIO' = traceM
main = replicateM_ 5 $ do trace1 trace2 where trace1 = traceIO' "trace1" trace2 = traceIO "trace2" --8<---------------cut here---------------end--------------->8---
when run via runghc (or compiled with -O0) for GHC 7.6, this emits
--8<---------------cut here---------------start------------->8--- trace1 trace2 trace2 trace2 trace2 trace2 --8<---------------cut here---------------end--------------->8---
only when using -O1 or -O2 the output results in
--8<---------------cut here---------------start------------->8--- trace1 trace2 trace1 trace2 trace1 trace2 trace1 trace2 trace1 trace2 --8<---------------cut here---------------end--------------->8---
(I'm guessing this due to `trace1` being inlined for -O1/-O2 -- but I haven't checked)
cheers, hvr
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
-- Andreas Abel <>< Du bist der geliebte Mensch.
Theoretical Computer Science, University of Munich Oettingenstr. 67, D-80538 Munich, GERMANY
andreas.abel@ifi.lmu.de http://www2.tcs.ifi.lmu.de/~abel/
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
What do you call these functions? I'll put them all into a patch and open a feature request for them all in one go. Chris On 21 January 2013 22:40, Roman Cheplyaka <roma@ro-che.info> wrote:
While we're at it, the trace functions I miss are
\x -> trace x x
and
\x -> trace (show x) x
Roman
* Andreas Abel <andreas.abel@ifi.lmu.de> [2013-01-21 23:31:24+0100]
+1. I also had to define traceM for the same purposes. --Andreas
On 21.01.13 6:41 PM, Chris Seaton wrote:
Yes, I suppose that traceIO does not have the semantics I assumed. Still, I think it is useful to have a trace that one can easily insert into an arbitrary monad. Here's how I use it:
--------
import Debug.Trace
main :: IO () main = putStrLn $ show foo
foo :: Maybe Int foo = do x <- bar 14 traceM $ show x y <- bar 2 traceM $ show y return $ x + y
bar :: Int -> Maybe Int bar x = Just $ 2*x
traceM :: (Monad m) => String -> m () traceM message = trace message $ return ()
----------
I think it is cleaner and more obvious than without the abstraction. Plus it is very easy to comment out. It is really good for list comprehensions written in do notation, as I often want to peek at intermediate values of those. I know I always add it to my projects, so I thought it may be wanted in base.
As Henning Thielemann said, you can use printf or whatever with it, but I think that is an orthogonal issue.
Regards,
Chris
On 21 January 2013 17:09, Herbert Valerio Riedel <hvr@gnu.org <mailto:hvr@gnu.org>> wrote:
Chris Seaton <chris@chrisseaton.com <mailto:chris@chrisseaton.com>> writes:
> I use printf-style debugging a lot, so I am always adding and removing > applications of trace. There is the Debug.Trace.traceIO function that makes > this easy to do in the IO monad (it just applies hPutStrLn stderr), but is > that specialisation to IO unnecessary? > > I find myself always using this utility function: > > traceM :: (Monad m) => String -> m () > traceM message = trace message $ return () > > Which can be used to implement traceIO. > > traceIO :: String -> IO () > traceIO = traceM
btw, that wouldn't have the same semantics as the existing `Debug.Trace.traceIO` which is more or less something similiar to a `hPutStrLn stderr` whose side-effect gets triggered at monad-execution time, whereas the side-effect of `traceM` occurs at monad-construction time; consider the following program:
--8<---------------cut here---------------start------------->8--- import Control.Monad import Debug.Trace
traceM :: (Monad m) => String -> m () traceM message = trace message $ return ()
traceIO' :: String -> IO () traceIO' = traceM
main = replicateM_ 5 $ do trace1 trace2 where trace1 = traceIO' "trace1" trace2 = traceIO "trace2" --8<---------------cut here---------------end--------------->8---
when run via runghc (or compiled with -O0) for GHC 7.6, this emits
--8<---------------cut here---------------start------------->8--- trace1 trace2 trace2 trace2 trace2 trace2 --8<---------------cut here---------------end--------------->8---
only when using -O1 or -O2 the output results in
--8<---------------cut here---------------start------------->8--- trace1 trace2 trace1 trace2 trace1 trace2 trace1 trace2 trace1 trace2 --8<---------------cut here---------------end--------------->8---
(I'm guessing this due to `trace1` being inlined for -O1/-O2 -- but I haven't checked)
cheers, hvr
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
-- Andreas Abel <>< Du bist der geliebte Mensch.
Theoretical Computer Science, University of Munich Oettingenstr. 67, D-80538 Munich, GERMANY
andreas.abel@ifi.lmu.de http://www2.tcs.ifi.lmu.de/~abel/
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
+1 I've used all three functions as well (and traceM probably the most). As for the other two, the names are probably not the best, but I've used these versions: traceMsgIt :: Show a => String -> a -> a traceMsgIt msg x = trace (msg++show x++"\n") x traceIt :: Show a => a -> a traceIt x = traceMsgIt "\nTraceIt:\n" x --Gershom On 1/24/13 10:14 AM, Chris Seaton wrote:
What do you call these functions? I'll put them all into a patch and open a feature request for them all in one go.
Chris
On 21 January 2013 22:40, Roman Cheplyaka <roma@ro-che.info <mailto:roma@ro-che.info>> wrote:
While we're at it, the trace functions I miss are
\x -> trace x x
and
\x -> trace (show x) x
Roman
* Andreas Abel <andreas.abel@ifi.lmu.de <mailto:andreas.abel@ifi.lmu.de>> [2013-01-21 23:31:24+0100] > +1. I also had to define traceM for the same purposes. --Andreas > > On 21.01.13 6:41 PM, Chris Seaton wrote: > >Yes, I suppose that traceIO does not have the semantics I assumed. > >Still, I think it is useful to have a trace that one can easily insert > >into an arbitrary monad. Here's how I use it: > > > >-------- > > > >import Debug.Trace > > > >main :: IO () > >main = putStrLn $ show foo > > > >foo :: Maybe Int > >foo = do > > x <- bar 14 > > traceM $ show x > > y <- bar 2 > > traceM $ show y > > return $ x + y > > > >bar :: Int -> Maybe Int > >bar x = Just $ 2*x > > > >traceM :: (Monad m) => String -> m () > >traceM message = trace message $ return () > > > >---------- > > > >I think it is cleaner and more obvious than without the abstraction. > >Plus it is very easy to comment out. It is really good for list > >comprehensions written in do notation, as I often want to peek at > >intermediate values of those. I know I always add it to my projects, so > >I thought it may be wanted in base. > > > >As Henning Thielemann said, you can use printf or whatever with it, but > >I think that is an orthogonal issue. > > > >Regards, > > > >Chris > > > > > > > >On 21 January 2013 17:09, Herbert Valerio Riedel <hvr@gnu.org <mailto:hvr@gnu.org> > ><mailto:hvr@gnu.org <mailto:hvr@gnu.org>>> wrote: > > > > Chris Seaton <chris@chrisseaton.com <mailto:chris@chrisseaton.com> <mailto:chris@chrisseaton.com <mailto:chris@chrisseaton.com>>> > > writes: > > > > > I use printf-style debugging a lot, so I am always adding and > > removing > > > applications of trace. There is the Debug.Trace.traceIO function > > that makes > > > this easy to do in the IO monad (it just applies hPutStrLn > > stderr), but is > > > that specialisation to IO unnecessary? > > > > > > I find myself always using this utility function: > > > > > > traceM :: (Monad m) => String -> m () > > > traceM message = trace message $ return () > > > > > > Which can be used to implement traceIO. > > > > > > traceIO :: String -> IO () > > > traceIO = traceM > > > > btw, that wouldn't have the same semantics as the existing > > `Debug.Trace.traceIO` which is more or less something similiar to a > > `hPutStrLn stderr` whose side-effect gets triggered at monad-execution > > time, whereas the side-effect of `traceM` occurs at monad-construction > > time; consider the following program: > > > > --8<---------------cut here---------------start------------->8--- > > import Control.Monad > > import Debug.Trace > > > > traceM :: (Monad m) => String -> m () > > traceM message = trace message $ return () > > > > traceIO' :: String -> IO () > > traceIO' = traceM > > > > main = replicateM_ 5 $ do > > trace1 > > trace2 > > where > > trace1 = traceIO' "trace1" > > trace2 = traceIO "trace2" > > --8<---------------cut here---------------end--------------->8--- > > > > when run via runghc (or compiled with -O0) for GHC 7.6, this emits > > > > --8<---------------cut here---------------start------------->8--- > > trace1 > > trace2 > > trace2 > > trace2 > > trace2 > > trace2 > > --8<---------------cut here---------------end--------------->8--- > > > > only when using -O1 or -O2 the output results in > > > > --8<---------------cut here---------------start------------->8--- > > trace1 > > trace2 > > trace1 > > trace2 > > trace1 > > trace2 > > trace1 > > trace2 > > trace1 > > trace2 > > --8<---------------cut here---------------end--------------->8--- > > > > (I'm guessing this due to `trace1` being inlined for -O1/-O2 -- but I > > haven't checked) > > > > cheers, > > hvr > > > > > > > > > >_______________________________________________ > >Libraries mailing list > >Libraries@haskell.org <mailto:Libraries@haskell.org> > >http://www.haskell.org/mailman/listinfo/libraries > > > > -- > Andreas Abel <>< Du bist der geliebte Mensch. > > Theoretical Computer Science, University of Munich > Oettingenstr. 67, D-80538 Munich, GERMANY > > andreas.abel@ifi.lmu.de <mailto:andreas.abel@ifi.lmu.de> > http://www2.tcs.ifi.lmu.de/~abel/ <http://www2.tcs.ifi.lmu.de/%7Eabel/> > > _______________________________________________ > Libraries mailing list > Libraries@haskell.org <mailto:Libraries@haskell.org> > http://www.haskell.org/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
I called it traceId. http://hackage.haskell.org/trac/ghc/ticket/7626 Chris On 24 January 2013 15:25, Gershom Bazerman <gershomb@gmail.com> wrote:
+1 I've used all three functions as well (and traceM probably the most).
As for the other two, the names are probably not the best, but I've used these versions:
traceMsgIt :: Show a => String -> a -> a traceMsgIt msg x = trace (msg++show x++"\n") x
traceIt :: Show a => a -> a traceIt x = traceMsgIt "\nTraceIt:\n" x
--Gershom
On 1/24/13 10:14 AM, Chris Seaton wrote:
What do you call these functions? I'll put them all into a patch and open a feature request for them all in one go.
Chris
On 21 January 2013 22:40, Roman Cheplyaka <roma@ro-che.info> wrote:
While we're at it, the trace functions I miss are
\x -> trace x x
and
\x -> trace (show x) x
Roman
* Andreas Abel <andreas.abel@ifi.lmu.de> [2013-01-21 23:31:24+0100]
+1. I also had to define traceM for the same purposes. --Andreas
On 21.01.13 6:41 PM, Chris Seaton wrote:
Yes, I suppose that traceIO does not have the semantics I assumed. Still, I think it is useful to have a trace that one can easily insert into an arbitrary monad. Here's how I use it:
--------
import Debug.Trace
main :: IO () main = putStrLn $ show foo
foo :: Maybe Int foo = do x <- bar 14 traceM $ show x y <- bar 2 traceM $ show y return $ x + y
bar :: Int -> Maybe Int bar x = Just $ 2*x
traceM :: (Monad m) => String -> m () traceM message = trace message $ return ()
----------
I think it is cleaner and more obvious than without the abstraction. Plus it is very easy to comment out. It is really good for list comprehensions written in do notation, as I often want to peek at intermediate values of those. I know I always add it to my projects, so I thought it may be wanted in base.
As Henning Thielemann said, you can use printf or whatever with it, but I think that is an orthogonal issue.
Regards,
Chris
On 21 January 2013 17:09, Herbert Valerio Riedel <hvr@gnu.org <mailto:hvr@gnu.org>> wrote:
Chris Seaton <chris@chrisseaton.com <mailto:chris@chrisseaton.com
writes:
> I use printf-style debugging a lot, so I am always adding and removing > applications of trace. There is the Debug.Trace.traceIO function that makes > this easy to do in the IO monad (it just applies hPutStrLn stderr), but is > that specialisation to IO unnecessary? > > I find myself always using this utility function: > > traceM :: (Monad m) => String -> m () > traceM message = trace message $ return () > > Which can be used to implement traceIO. > > traceIO :: String -> IO () > traceIO = traceM
btw, that wouldn't have the same semantics as the existing `Debug.Trace.traceIO` which is more or less something similiar to a `hPutStrLn stderr` whose side-effect gets triggered at monad-execution time, whereas the side-effect of `traceM` occurs at monad-construction time; consider the following program:
--8<---------------cut here---------------start------------->8--- import Control.Monad import Debug.Trace
traceM :: (Monad m) => String -> m () traceM message = trace message $ return ()
traceIO' :: String -> IO () traceIO' = traceM
main = replicateM_ 5 $ do trace1 trace2 where trace1 = traceIO' "trace1" trace2 = traceIO "trace2" --8<---------------cut here---------------end--------------->8---
when run via runghc (or compiled with -O0) for GHC 7.6, this emits
--8<---------------cut here---------------start------------->8--- trace1 trace2 trace2 trace2 trace2 trace2 --8<---------------cut here---------------end--------------->8---
only when using -O1 or -O2 the output results in
--8<---------------cut here---------------start------------->8--- trace1 trace2 trace1 trace2 trace1 trace2 trace1 trace2 trace1 trace2 --8<---------------cut here---------------end--------------->8---
(I'm guessing this due to `trace1` being inlined for -O1/-O2 -- but I haven't checked)
cheers, hvr
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
-- Andreas Abel <>< Du bist der geliebte Mensch.
Theoretical Computer Science, University of Munich Oettingenstr. 67, D-80538 Munich, GERMANY
andreas.abel@ifi.lmu.de http://www2.tcs.ifi.lmu.de/~abel/
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
_______________________________________________ Libraries mailing listLibraries@haskell.orghttp://www.haskell.org/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
Note that traceM won't work correctly for monads that are not strict in the first argument of >>=, e.g. the Identity monad. For example, this will not print anything: runIdentity $ traceM "test" >> return () On Mon, Jan 21, 2013 at 11:48 AM, Chris Seaton <chris@chrisseaton.com>wrote:
I use printf-style debugging a lot, so I am always adding and removing applications of trace. There is the Debug.Trace.traceIO function that makes this easy to do in the IO monad (it just applies hPutStrLn stderr), but is that specialisation to IO unnecessary?
I find myself always using this utility function:
traceM :: (Monad m) => String -> m () traceM message = trace message $ return ()
Which can be used to implement traceIO.
traceIO :: String -> IO () traceIO = traceM
That way I can traceM in whatever monad I am in. It is easier to add and remove an application of trace, because I do not have to wrap it around something, and I do not have to remember the return. Of course, you are still subject to however your monad chooses to order the execution of these traces, but that is what people expect when using trace.
Would traceM be a wanted addition to Debug.Trace?
Regards,
Chris Seaton
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
Agreed, but I think that's the behaviour that you expect when tracing, and when you trace in a monad you would expect get the semantics of that monad as well. For example, you may be using traceM to check that your monad has the strictness behaviour that you expect. I usually use traceM to view temporary values in a list or maybe comprehension, and then the semantics are obvious because I'm tracing a value that is about to be consumed by the next stage in the pipeline. I could add some notes about it being best applied with certain monads. Chris On 25 January 2013 16:44, Patrick Palka <patrick@parcs.ath.cx> wrote:
Note that traceM won't work correctly for monads that are not strict in the first argument of >>=, e.g. the Identity monad.
For example, this will not print anything: runIdentity $ traceM "test" >> return ()
On Mon, Jan 21, 2013 at 11:48 AM, Chris Seaton <chris@chrisseaton.com>wrote:
I use printf-style debugging a lot, so I am always adding and removing applications of trace. There is the Debug.Trace.traceIO function that makes this easy to do in the IO monad (it just applies hPutStrLn stderr), but is that specialisation to IO unnecessary?
I find myself always using this utility function:
traceM :: (Monad m) => String -> m () traceM message = trace message $ return ()
Which can be used to implement traceIO.
traceIO :: String -> IO () traceIO = traceM
That way I can traceM in whatever monad I am in. It is easier to add and remove an application of trace, because I do not have to wrap it around something, and I do not have to remember the return. Of course, you are still subject to however your monad chooses to order the execution of these traces, but that is what people expect when using trace.
Would traceM be a wanted addition to Debug.Trace?
Regards,
Chris Seaton
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
participants (8)
-
Andreas Abel -
Chris Seaton -
Gershom Bazerman -
Henning Thielemann -
Herbert Valerio Riedel -
Isaac Dupree -
Patrick Palka -
Roman Cheplyaka