Skip to content

MPTC and canonical wrappers #37

@treeowl

Description

@treeowl

I've never been the biggest fan of single-parameter classes with buried type families. Could we add an MPTC version of PrimUnlifted?

class (PrimUnlifted a, Unlifted a ~ ua) => PU ua a
instance (PrimUnlifted a, Unlifted a ~ ua) => PU ua a

That thinking leads me to the possibility of a class for types that have a "canonical wrapper":

class PrimUnlifted (Lifted ua) => PrimUnliftedC ua where
  type Lifted ua :: Type
instance PrimUnliftedC (Array# a) where
  type Lifted (Array# a) = Array a
instance PrimUnliftedC (MVar# a) where
  type Lifted (MVar# a) = MVar a
instance PrimUnliftedC (Weak# a) where
  type Lifted (Weak# a) = Weak a

toUnliftedC# :: forall a ua. (PrimUnliftedC ua, ua ~  Unlifted a) => a -> ua
toUnliftedC# = toUnlifted#

fromUnliftedC# :: forall ua a. (PrimUnliftedC ua, ua ~ Unlifted a) => ua -> a
fromUnliftedC# = fromUnlifted#

class (PU ua a, Lifted ua ~ a) => PUC ua a
instance (PU ua a, Lifted ua ~ a) => PUC ua a

toUnliftedC# :: PUC ua a => a -> ua
toUnliftedlC# = toUnlifted#

fromUnliftedC# :: PUC ua a => ua -> a
fromUnliftedC# = fromUnlifted#

For many types, unfortunately, there's no good answer to the canonical instance question. For example, we can only pick one of the following instances:

instance PrimUnliftedC (MutVar# s a) where
  type Lifted (MutVar# s a) = STRef s a
instance s ~ RealWorld => PrimUnliftedC (MutVar# s a) where
  type Lifted  (MutVar# s a) = IORef a

That leads to the possibility of PrimUnliftedC being an empty class with just one instance, and having Lifted as an independent type family.

Bleh.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions