Discussion:
Proposal: Debug.Trace.traceWith
Kris Nuttycombe
2018-02-10 01:08:28 UTC
Permalink
When using Debug.Trace for debugging, a very common operation is to prefer
to trace only some subset or function of an intermediate result. As a
consequence, I propose adding the following function to Debug.Trace:

traceWith :: (Show b) => (a -> b) -> a -> a
traceWith f a = trace (show $ f a) a

While it's trivial to define, I have found this to be one of the most
useful functions in my trace-based debugging toolkit, hence my proposal
that it be added to base. It generalizes `traceShowId` in a meaningful and
useful fashion.

As this is the first such proposal I've put forth, please let me know if
I'm doing anything wrong with it!

Thanks,

Kris Nuttycombe
Theodore Lief Gannon
2018-02-10 02:32:29 UTC
Permalink
Hearty +1 one to this. Note:

traceShowId = traceWith id
traceShow = traceWith . const
Post by Kris Nuttycombe
When using Debug.Trace for debugging, a very common operation is to prefer
to trace only some subset or function of an intermediate result. As a
traceWith :: (Show b) => (a -> b) -> a -> a
traceWith f a = trace (show $ f a) a
While it's trivial to define, I have found this to be one of the most
useful functions in my trace-based debugging toolkit, hence my proposal
that it be added to base. It generalizes `traceShowId` in a meaningful and
useful fashion.
As this is the first such proposal I've put forth, please let me know if
I'm doing anything wrong with it!
Thanks,
Kris Nuttycombe
_______________________________________________
Libraries mailing list
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
David Feuer
2018-02-10 03:07:59 UTC
Permalink
Other another bike-shed color:

traceWith :: (a -> String) -> a -> a
traceWith f a = trace (f a) a

traceShowWith :: Show b => (a -> b) -> a -> a
traceShowWith f = traceWith (show . f)

But on the other hand, pointfree.io tells me that you can write

trace =<< f
trace =<< show . f

so I'm not sure how urgent these are.

On Feb 9, 2018 8:08 PM, "Kris Nuttycombe" <***@gmail.com> wrote:

When using Debug.Trace for debugging, a very common operation is to prefer
to trace only some subset or function of an intermediate result. As a
consequence, I propose adding the following function to Debug.Trace:

traceWith :: (Show b) => (a -> b) -> a -> a
traceWith f a = trace (show $ f a) a

While it's trivial to define, I have found this to be one of the most
useful functions in my trace-based debugging toolkit, hence my proposal
that it be added to base. It generalizes `traceShowId` in a meaningful and
useful fashion.

As this is the first such proposal I've put forth, please let me know if
I'm doing anything wrong with it!

Thanks,

Kris Nuttycombe
Joachim Breitner
2018-02-10 19:40:00 UTC
Permalink
Hi,
Post by David Feuer
traceWith :: (a -> String) -> a -> a
traceShowWith :: Show b => (a -> b) -> a -> a
traceShowWith f = traceWith (show . f)
so many bike-shed colors! Maybe an indication that not all of them are
needed, but we should rather be better at pointing to useful, concice
and non-obvoius idioms?
Post by David Feuer
But on the other hand, pointfree.io tells me that you can write
trace =<< f
trace =<< show . f
so I'm not sure how urgent these are.
Nifty! If we add this prominently to the docs in Data.Trace, wouldn’t
that suit us better?

Cheers,
Joachim
--
Joachim Breitner
***@joachim-breitner.de
http://www.joachim-breitner.de/
Michael Sloan
2018-02-10 14:48:21 UTC
Permalink
I often define

tracer prefix x = trace (prefix ++ ": " ++ show x) x

A bit arbitrary with the choice of ": ", but quite convenient. The with
variant would be

tracerWith prefix f x = trace (prefix ++ ": " ++ show (f x)) x

On Feb 9, 2018 5:09 PM, "Kris Nuttycombe" <***@gmail.com> wrote:

When using Debug.Trace for debugging, a very common operation is to prefer
to trace only some subset or function of an intermediate result. As a
consequence, I propose adding the following function to Debug.Trace:

traceWith :: (Show b) => (a -> b) -> a -> a
traceWith f a = trace (show $ f a) a

While it's trivial to define, I have found this to be one of the most
useful functions in my trace-based debugging toolkit, hence my proposal
that it be added to base. It generalizes `traceShowId` in a meaningful and
useful fashion.

As this is the first such proposal I've put forth, please let me know if
I'm doing anything wrong with it!

Thanks,

Kris Nuttycombe
Kris Nuttycombe
2018-02-10 16:53:44 UTC
Permalink
Post by Michael Sloan
I often define
tracer prefix x = trace (prefix ++ ": " ++ show x) x
I also have `traceWithPrefix :: (Show b) -> String -> (a -> b) -> a -> a`
defined, for the same reason, so I absolutely support adding that as well.
Post by Michael Sloan
A bit arbitrary with the choice of ": ", but quite convenient. The with
variant would be
tracerWith prefix f x = trace (prefix ++ ": " ++ show (f x)) x
The definition I use is simply

traceWithPrefix p f a = trace (p ++ show (f a)) a
Post by Michael Sloan
traceWith :: (a -> String) -> a -> a
traceWith f a = trace (f a) a
traceShowWith :: Show b => (a -> b) -> a -> a
traceShowWith f = traceWith (show . f)
Is there some situation where the `Show String` instance wouldn't be in
scope? If `b` is `String` it works out just fine, so the first definition
you gave here seems superfluous.
Post by Michael Sloan
But on the other hand, pointfree.io tells me that you can write
trace =<< f
trace =<< show . f
That's... remarkably clever, so clever that it never occurred to me in 4
years of writing Haskell. :) I see your point, but jumping to the `Monad
Reader` instance is a bit surprising. At very least, maybe this approach
ought to be documented in the module. Thanks for pointing it out!

So, a question for all: if I were to want to create a pull request to add
these functions (traceWith and traceWithPrefix) where would I go to do so?

Thanks,

Kris
Post by Michael Sloan
When using Debug.Trace for debugging, a very common operation is to prefer
to trace only some subset or function of an intermediate result. As a
traceWith :: (Show b) => (a -> b) -> a -> a
traceWith f a = trace (show $ f a) a
While it's trivial to define, I have found this to be one of the most
useful functions in my trace-based debugging toolkit, hence my proposal
that it be added to base. It generalizes `traceShowId` in a meaningful and
useful fashion.
As this is the first such proposal I've put forth, please let me know if
I'm doing anything wrong with it!
Thanks,
Kris Nuttycombe
_______________________________________________
Libraries mailing list
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
David Feuer
2018-02-10 17:09:32 UTC
Permalink
Post by David Feuer
traceWith :: (a -> String) -> a -> a
traceWith f a = trace (f a) a
traceShowWith :: Show b => (a -> b) -> a -> a
traceShowWith f = traceWith (show . f)
Is there some situation where the `Show String` instance wouldn't be in
scope? If `b` is `String` it works out just fine, so the first definition
you gave here seems superfluous.


If the strings have non-ASCII characters, show will mangle them.
David Feuer
2018-02-10 17:10:34 UTC
Permalink
Also, if you're pretty-printing something to use with trace, show will
knock off the alignment and such.
Post by Kris Nuttycombe
Post by David Feuer
traceWith :: (a -> String) -> a -> a
traceWith f a = trace (f a) a
traceShowWith :: Show b => (a -> b) -> a -> a
traceShowWith f = traceWith (show . f)
Is there some situation where the `Show String` instance wouldn't be in
scope? If `b` is `String` it works out just fine, so the first definition
you gave here seems superfluous.
If the strings have non-ASCII characters, show will mangle them.
Kris Nuttycombe
2018-02-10 17:18:03 UTC
Permalink
Ah, that makes sense, I forgot about the escaping issues.
Post by Kris Nuttycombe
Post by David Feuer
traceWith :: (a -> String) -> a -> a
traceWith f a = trace (f a) a
traceShowWith :: Show b => (a -> b) -> a -> a
traceShowWith f = traceWith (show . f)
Is there some situation where the `Show String` instance wouldn't be in
scope? If `b` is `String` it works out just fine, so the first definition
you gave here seems superfluous.
If the strings have non-ASCII characters, show will mangle them.
Loading...