1

I have learned that point-free style is preferred in the Haskell community, and I often write expressions like this:

naive = (slugifyUnicode . T.take maxFilenameSize . T.pack . stripHtmlTags . T.unpack . plainToHtml) sfld

However, while debugging, I find myself repeatedly converting expressions like this into chains of $ operators in order to use some variant of trace, and I am starting to think it is preferable to forgo the point-free style and just write lots of $s to start with, in order to make debugging less cumbersome. After all, it ends up being about the same number of characters.

Does anyone know of a way to debug long chains of composed functions without de-composing them?

And more generally, any comments on this inconvenience are very welcome.

6
  • 1
    "I have learned that point-free style is preferred in the Haskell community" -- note that's not always the case. From what I observed, the community loves point-free style only when it leads to elegant and clear code. However, in many cases applying point-free leads to a mess, and it is jokingly referred to as "point-less style" by the community. In your case, the code is nice, but be careful. Also, f . g . h $ x works as expected and is quite idiomatic. Commented Dec 26, 2022 at 11:43
  • "Point-free style is preferred by the community?" What? Commented Dec 26, 2022 at 13:59
  • What would naive look like after you un-point-free'd it and inserted a trace? Commented Dec 26, 2022 at 14:40
  • @LouisWasserman I would be happy to be told I'm wrong. I am not an oracle for the consensus opinion of all users, obviously. Commented Dec 26, 2022 at 15:07
  • @DanielWagner I would usually break half of it into an intermediate value defined in a where clause, trace it there, and then do the rest of the computation at the original site of the expression. Commented Dec 26, 2022 at 15:08

1 Answer 1

3

For any intermediate value that has a Show instance you can just use traceShowId inline:

naive = (slugifyUnicode . T.take maxFilenameSize . traceShowId . T.pack . stripHtmlTags . T.unpack .plainToHtml) sfld

If the intermediary value is a String you can use traceId instead.

For anything that doesn't have a Show instance you'd have to define a helper:

data CustomType = CustomType String
traceHelper :: CustomType -> CustomType
traceHelper s@(CustomType c) = trace c $ s

-- arbitrary functions we want to compose
a :: aIn -> CustomType
b :: CustomType -> bOut

c :: aIn -> bOut
c = b . traceHelper . a
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.