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
Currently, you use
The trouble is that this sprays
ULconstructors all through the type-aligned sequence.Once #2 is fixed, there's another (somewhat disgusting) way that seems reasonably likely to be safe:
Here's the nasty bit:
Now