8

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
                   }
Community
  • 1
  • 1
levant pied
  • 3,886
  • 5
  • 37
  • 56

2 Answers2

8

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.

gb.
  • 4,629
  • 1
  • 20
  • 19
  • Thanks gb., I always thought of records as similar to primitive types. – levant pied Feb 17 '17 at 23:54
  • How do you do this when your newtype/data declaration has a type variable? I.e. it's `* -> *` rather than just `*`. – rgrinberg Jul 13 '17 at 06:29
  • 1
    You need to inclue a constraint on the type variable too. So instead of `instance name :: Class Type` you'd have `instance name :: Class a => Class (Type a)`. – gb. Jul 13 '17 at 10:34
  • 1
    Now in `Data.Show.Generic`: https://pursuit.purescript.org/packages/purescript-prelude/5.0.1/docs/Data.Show.Generic#t:GenericShow – Peter Becich May 30 '21 at 02:35
1

Instances are used to define blueprints for creating objects with similar properties.

show can be used to convert types into string type, but since types such as Int, String, etc already have a instance of show so we don't really have to define one but types which are user defined has no instances and we have to define one to actually use show.

on the other hand for debugging purpose we can use spy to print any types into console without actually defining instances.

Ashish Singh
  • 97
  • 1
  • 3