Skip to content

how does derivingVia interact with class constraints or quantified constraints?

a friend recently wanted to write some instances of a new type, using deriving via

he started with

newtype TimeDerived t (s :: Symbol) = DT { actualTime :: t }
....
  deriving Serial via (Time t s) --- Serial is a type class in the bytes package that abstracts over Cereal et al

which didn't type check because ghc doesn't know how to coerce through an unknown monad (roles!),

after a bit of tweaking i was able to write the following


newtype TimeDerived t (s :: Symbol) = DT { actualTime :: t }
...
--  deriving Serial via (Time t s)
-- how can this instance be expressed using quantified constraints and or deriving via?
instance (KnownSymbol s , ParseTime t, FormatTime t)=>S.Serial (TimeDerived t (s:: Symbol) ) where
--- this fmap will be optimized to coerce! right?
  serialize = S.serialize .  (coerce ::  TimeDerived t s -> Time t s  )

  deserialize = fmap (coerce :: Time t s -> TimeDerived t s )$ S.deserialize

the file and commit and associated repo can be found here https://code.xkrd.net/haskell/deriving-time/blob/f303a661bfd28eb83925945426bf3ff287fda67a/test/Test.hs#L28-43

the point being: this code seems EEERILY close to what should be expressible with some smart admixture of DerivingVia, Coercible, and Quantified constraints, But i'm not even sure if we can express this example properly with those tools today!

cc @RyanGlScott @Icelandjack

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information