Constrained Dynamic variant

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Constrained Dynamic variant

Ryan Reich
I have found it useful to use Dynamic-like existential types such as (fake example):

> 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.

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Constrained Dynamic variant

David Feuer
You can make relaxation kind of work using a lens-like trick:

type CDynamic (c :: * -> Constraint) =
  forall r. (forall a. (Typeable a, c a) => a -> r) -> r

The trouble is that ambiguous types start to pop up pretty quickly, so
I don't know that this would really be a practical approach.

On Wed, Dec 27, 2017 at 2:33 AM, Ryan Reich <[hidden email]> wrote:

> I have found it useful to use Dynamic-like existential types such as (fake
> example):
>
>> 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.
>
> _______________________________________________
> Libraries mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries