Search code examples
pattern-matchingpurescriptnewtype

How to neatly deconstruct newtypes nested into records?


I use a newtype as field of a record, and pattern matching on the "parent" type to extract the nested value is cumbersome:

newtype CityName = CityName String
newtype City = City {
  name :: CityName
}
instance showCity :: Show City where
  show (City { name }) = case name of (CityName cn) -> "City(" <> cn <> ")"

I can deconstruct the "parent" type, but then I use another pattern matching to extract the wrapped String - even if the newtype only has one data constructor. It would be more convenient to deconstruct the whole type in just one pattern.

Is this possible? If so, I cannot get the syntax right. I tried something like show (City { name :: (CityName cn) }) = cn but it gives me syntax errors. PureScript by Example did not help me either, but maybe there is neater way to do what I want?


Solution

  • What you tried is almost right, but you only need a single colon when pattern matching records:

    instance showCity :: Show City where
      show (City { name: CityName cn }) = "City(" <> cn <> ")"
    

    Double colon is only used for annotating types, value level stuff always uses a single colon.