Constrained Dynamic variant

Ryan Reich ryan.reich at
Wed Dec 27 07:33:09 UTC 2017

I have found it useful to use Dynamic-like existential types such as (fake

> data Number = forall a. (Num a, Typeable a) => Number a

which supports precisely the same API as Dynamic, but with a Num constraint
on everything.  However, writing that API for this particular type requires
copy-pasting the definitions of fromDyn and fromDynamic as boilerplate,
which is (ahem) stupid.  Now that we have the Constraint kind, it is
possible to generalize this in a form suitable for Data.Dynamic:

> data CDynamic (c :: Type -> Constraint) = forall a. (c a) => CDynamic
(TypeRep a) a
> toCDyn :: (c a, Typeable a) => a -> CDynamic c
> fromCDyn :: (c a, Typeable a) => CDynamic c -> a -> a
> fromCDynamic :: (c a, Typeable a) => CDynamic c -> Maybe a
> relaxCDyn :: CDynamic c -> Dynamic
> dynApplyC :: CDynamic c1 -> CDynamic c2 -> Maybe Dynamic
> dynAppC :: CDynamic c1 -> CDynamic c2 -> Dynamic
> dynTypeRepC :: CDynamic c -> SomeTypeRep
> instance Show (CDynamic c)
> instance Exception (CDynamic c)
> class NoC a where -- intentionally empty, can be used unsaturated
> instance NoC a where -- also empty
> type Dynamic = CDynamic NoC
> -- Specializations of all the above functions

I think it's clear how to fill in the definitions.  I added an apparently
necessary function relaxCDyn that also does the obvious thing; I'm not
really happy with its type signature but offhand I can't say how to
generalize it.

I think this is useful, and if I'm not missing anything (obvious or subtle)
about it, I want to propose that it goes into Data.Dynamic.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the Libraries mailing list