A possible Userland method of reducing Newtype boilerplate for functions that are not part of a typeclass

Hi!
I’ve been recently learning purescript, and I have learnt about the Orphan Rule in Purescript, and specifically how orphan instances are fully disallowed in PS.

I, for example, wanted to deserialize/serialize a record with Argonaut, containing a UUID, and sadly purescript-uuid contains no implementations for Argonaut, meaning my only options were an orphan instance or a newtype.

No problem, I thought, I can simply derive newtype instance and be done with it!

Sadly, newtype deriving only works on typeclasses, and most useful functions in the uuid library are not within typeclasses, meaning I was out of luck.

I learned I could manually lift the function signatures over the newtype using the Applicative and other typeclasses, but that meant manually deriving and applying the transformation, which being a programmer, needlessly tried to automate.

So I built this:

It’s a typeclass that will automatically lift any function/value over a newtype, through any functors, bifunctors, profunctors, records, tuples, functions, you name it!

Therefore the usage is as such, with my UUID example:

module Data.UUID.Newtyped (UUID(..),emptyUUID, genUUID   ,parseUUID ,genv3UUID ,genv5UUID ,toString) where

import Data.Eq
import Data.Newtype
import Data.Newtype.Lift
import Data.Ord
import Data.Show

import Data.UUID as X


newtype UUID = UUID X.UUID
derive instance Newtype UUID _
derive newtype instance Show    UUID
derive newtype instance Eq      UUID
derive newtype instance Ord     UUID

lift' = lift @UUID @(X.UUID)

emptyUUID = lift' X.emptyUUID
genUUID   = lift' X.genUUID
parseUUID = lift' X.parseUUID
genv3UUID = lift' X.genv3UUID
genv5UUID = lift' X.genv5UUID
toString  = lift' X.toString 

Which is still a bit boilerplaty, but certainly better than before.

The use of instance chains means I find it kinda difficult to extend this system for any other types for which I provide no implementation, but I thought it was a start.

I post here to get some feedback on this code, whether someone has already done this, and if not, if it’s any good to publish as a small library!

I appreciate all constructive feedback. Cheers!

1 Like