[ghc-steering-committee] #364: Unify Nat and Natural, recommendation: accept

Joachim Breitner mail at joachim-breitner.de
Thu Oct 1 16:44:57 UTC 2020


Hi,

Am Donnerstag, den 01.10.2020, 09:14 -0700 schrieb Iavor Diatchki:
> Joachim, I'd be curious to see an example of the hurdle you run into, if there is a simple example illustrating it.

I wanted to use a datatype (that describes an typed AST) both as values
(where I needed Text or String) and as types (where needed Symbol). I
resorted to a hack like

data FieldName
   = N Symbol -- ^ a properly named field
   | N' T.Text -- ^ Use this in terms (usually not needed)
   | H Nat -- ^ a field hash. Should fit in 32 bit. Also used for tuples 
   | H' Word32 -- ^ Use this in terms (mostly internal)


data SFieldName (n :: FieldName) where
    SN :: KnownSymbol s => Proxy s -> SFieldName ('N s)
    SH :: KnownNat n => Proxy n -> SFieldName ('H n)

fromSFieldName :: SFieldName n -> FieldName
fromSFieldName (SN p) = N' (T.pack (symbolVal p))
fromSFieldName (SH p) = H' (fromIntegral (natVal p))

class Typeable fn => KnownFieldName (fn :: FieldName) where fieldName :: SFieldName fn
instance KnownSymbol s => KnownFieldName ('N s) where
    fieldName = SN (Proxy @s)
instance KnownNat s => KnownFieldName ('H s) where
    fieldName = SH (Proxy @s)

Fullcode at 
https://github.com/nomeata/haskell-candid/blob/2feb0cdbdbfa74f3e4373066b1d5827e5038df9d/src/Codec/Candid/Core.hs#L163-L167

Eventually I just used less type-level computation (and otherwise
greatly restructued that code, so don’t worry too much about helping
here). Maybe using a library like singleton might have made that
easier, or maybe there are tricks that I missed, and I did it all
wrong.


Cheers,
Joachim
-- 
Joachim Breitner
  mail at joachim-breitner.de
  http://www.joachim-breitner.de/




More information about the ghc-steering-committee mailing list