Skip to content

Make Data.LowerTSequence more efficient #3

@treeowl

Description

@treeowl

Currently, you use

data AsUnitLoop a b c where 
   UL :: !a -> AsUnitLoop a () ()
newtype MSeq s a = MSeq { getMS :: s (AsUnitLoop a) () () }

The trouble is that this sprays UL constructors all through the type-aligned sequence.

Once #2 is fixed, there's another (somewhat disgusting) way that seems reasonably likely to be safe:

newtype AsUnitLoop a (b :: Void) (c :: Void) = UL a

data MSeq (s :: (Void -> Void -> *) -> Void -> Void -> *) a where
  MSeq :: { getMS :: !(s (AsUnitLoop a) i j) } -> MSeq s a

Here's the nasty bit:

voidEqual :: forall p q . (p :: Void) :~: (q :: Void)
voidEqual = unsafeCoerce (Refl :: p :~: p)

Now

instance TSequence s => Sequence (MSeq (s :: (Void -> Void -> *) -> Void -> Void -> *)) where
  empty      = MSeq tempty
  singleton  = MSeq . tsingleton . UL
  MSeq (l :: s (AsUnitLoop a) i j) .>< MSeq (r :: s (AsUnitLoop a) m n) =
    case voidEqual :: j :~: m of
      Refl -> MSeq $ l >< r
  MSeq l .|> x    = MSeq $ l |> UL x
  x .<| MSeq r    = MSeq $ UL x <| r
  viewl (MSeq s)   = case tviewl s of
     TEmptyL      -> EmptyL
     UL h :| t -> h :< MSeq t
  viewr  (MSeq s)   = case tviewr s of
     TEmptyR      -> EmptyR
     p :|< UL l -> MSeq p :> l

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions