Python's print in Haskell 2022.07.28

Python's print function doesn't quote strings like Haskell's does. Suppose you wanted that:

main = do
    pyPrint "Hello!" -- Prints Hello! (without quotes)
    pyPrint (1, "a") -- Prints (1,"a")

This can be implemented without overlapping instances as follows:

{-# LANGUAGE FlexibleInstances, UndecidableInstances, DataKinds, TypeFamilies #-}

import Data.Proxy
import TypeFun.Data.Eq (Equal) -- From "type-fun" package

pyPrint :: PyStr a => a -> IO ()
pyPrint = putStrLn . pyStr

class PyStr a where pyStr :: a -> String

class PyStrHelper a where pyStrHelper :: a -> String
instance PyStrHelper (Proxy True, String) where pyStrHelper = snd
instance Show a => PyStrHelper (Proxy False, a) where pyStrHelper = show . snd

instance PyStrHelper (Proxy (Equal String a), a) => PyStr a where
    pyStr = pyStrHelper . ((,) Proxy :: a -> (Proxy (Equal String a), a))

Good idea or not

I'm writing this post because I'm currently considering a similar solution for processing the types AST of Lamdu.

This AST is parameterized on whether we're displaying an inferred type, which doesn't have edit and refactoring actions available, or whether it is a user-editable type like the definition of a nominal type.

Lamdu's name-presentation AST pass should have instances that work on both variants and this technique appears to allow that.

What do you think? Is this a good idea?