purescript

Purescript default `Show` instance for records


I saw this question:

where I found out I can use purescript-debug to print it, e.g. by using:

> traceAny {a:1} id
{ a: 1 }
unit

I was wondering however what is the rationale behind not having a default Show instance for records:

> {a:1}
Error found:
in module $PSCI

  No type class instance was found for

    Data.Show.Show { "a" :: Int
                   }

Solution

  • Show is just implemented as library code, so there's no way an instance can be written that can accomodate every possible record. There would need to be some kind of constraint where you could say "the type of every value in this record must also have a Show instance", for example. The actual implementation would need to be somewhat magic too, since you can't iterate over the labels in a record either.

    There have been a few discussions about reforming Show, such as this one, that would potentially solve this, by making Show entirely magic, and only usable for debugging purposes.

    Although this doesn't really solve the case you have here, it is possible to rely on Generic deriving to make a Show instance for a newtype'd record, which can take some of the pain out of this kind of thing:

    import Data.Generic (class Generic, gShow)
    
    newtype MyRecord = MyRecord { a :: Int }
    
    derive instance genericMyRecord :: Generic MyRecord
    
    instance showMyRecord :: Show MyRecord where
      show = gShow
    

    And if you derive Newtype too it makes the record easier to work with as you can use the various operations that help with wrapping/unwrapping/operating under the newtype, etc.