Opened 2 years ago
Last modified 2 years ago
#13592 new feature request
Newtype type class with compiler generated instances
Reported by: | Iceland_jack | Owned by: | |
---|---|---|---|
Priority: | normal | Milestone: | |
Component: | Compiler | Version: | 8.0.1 |
Keywords: | LevityPolymorphism | Cc: | |
Operating System: | Unknown/Multiple | Architecture: | Unknown/Multiple |
Type of failure: | None/Unknown | Test Case: | |
Blocked By: | Blocking: | ||
Related Tickets: | Differential Rev(s): | ||
Wiki Page: |
Description
Define a Newtype
class, autmatically generating instances
class Newtype n where type O n :: Type pack :: O n -> n unpack :: n -> O n
as defined in Conal's Generic parallel functional programming but also found in the newtype and lens packages.
I run into this class every once in a while
Change History (5)
comment:1 Changed 2 years ago by
comment:5 Changed 2 years ago by
Keywords: | LevityPolymorphism added |
---|
ala:
ala Sum foldMap [1,2] :: Num o => o
while coerce
lacks a way to connect a newtype to its associated type
ala Sum foldMap [1,2] :: Coercible o o' => Num o => o'
but it could certainly re-use Coercible
either as default methods — compiler only needs to generate instance Newtype (Sum a) where type O (Sum a) = a
class Newtype n where type O n pack :: O n -> n pack = coerce default pack :: O n `Coercible` n => O n -> n unpack :: n -> O n unpack = coerce default unpack :: n `Coercible` O n => n -> O n
or with Coercible
as a superclass — compiler only needs to generate type instance O (Sum a) = a
and Newtype
is definable by users
class O n `Coercible` n => Newtype n instance O n `Coercible` n => Newtype n -- type instance O (a, b) = (O a, O b) pack :: Newtype n => O n -> n pack = coerce unpack :: Newtype n => n -> O n unpack = coerce
I see some problems with newtypes wrapping polymorphic values, #13901
newtype Nat = Nat (forall a. (a -> a) -> (a -> a)) -- • Illegal polymorphic type: forall a. (a -> a) -> (a -> a) -- • In the equations for closed type family ‘O’ type instance O Nat = forall a. (a -> a) -> (a -> a)
TODO With newtypes over unlifted types and levity polymorphic Coercible
(#13595) we can define
newtype MyInt = MkInt Int newtype MyInt# = MkInt# Int# -- ==> type family O (a :: TYPE rep) :: TYPE rep type instance O MyInt = Int type instance O MyInt# = Int#
I'm leery about adding more magic classes to GHC, but fortunately, this magic already exists as
Data.Coerce.Coercible
:Does this suit your needs?