Is there an easier way to print variables with Debug.Trace?

Currently I do the following when I want to print a variable for debugging:

{-# LANGUAGE BangPatterns #-}

import Debug.Trace (trace)

someFunc :: Int -> Int
someFunc n = result where
    result = n^2
    !result_ = trace ("result: " ++ show result) ()

I’m wondering if there is an easier way to achieve the same thing. What I’m looking for is a function, e.g. debug, like this:

someFunc :: Int -> Int
someFunc n = result where
    result = n^2
    debug "result: " result

How can I define such a function, assuming result is an instance of Show? Also, I don’t want to enable the BangPatterns extension in every module I want to debug.

EDIT: Probably it’s not possible since I need at least one assignment.

2 Likes

As a side note, I’d be inclined to use

!() = trace expr ()

otherwise there’s a risk that you write

!result_ = trace expr

by accident, and don’t trace anything at all.

3 Likes

I think the easiest way to make sure the debug function is evaluated is to put it inside the definition of result, like this:

import Debug.Trace (trace)

debug :: Show a => String -> a -> a
debug s a = trace (s ++ show a) a

someFunc :: Int -> Int
someFunc n = result where
    result = debug "result: " (n^2)

If you really want to keep your debug function separate from your definition of result, I can’t think of a way to improve on what you have now.

4 Likes

Found a solution that comes close. Now I can simply comment/uncomment the line with the question mark. Is there any problem with doing it this way?

infix 0 ?
(?) :: Show a => a -> String -> a
(?) a s = trace (s ++ show a) a

someFunc :: Int -> Int
someFunc n = result where
    result = n^2 
        ? "result: "
3 Likes

That solution looks fine to me!

1 Like

GHC 9.4 has this:

someFunc :: Int -> Int
someFunc n =
  traceShowWith ("result",) $ -- you can comment this out
    n ^ 2

or, if you don’t like extra parens in output:

someFunc :: Int -> Int
someFunc n =
  traceWith (mappend "result: " . show) $ -- you can comment this out
    n ^ 2
9 Likes

Helpers like dbg1 in Hledger.Utils.Debug might be useful/give ideas.

3 Likes

traceShowId. Will print the variable with no ability to modify the resulting information.

traceWith ((<> “myComment”). show) or traceWith ((“myComment” <>). show) lets you append a string instead to the resulting comment.

1 Like