As discussed in comments on #789, it can be pretty hard to avoid space leaks and such when capturing indexed traversals. Here's one idea. There are a few ways to wiggle it, but you should get the idea.
class (Profunctor p, Functor f, f ~ Fun p) => Cosieve p f where
type Fun p :: * -> *
cosieve :: p a b -> f a -> b
-- The only reason to separate this from Cosieve is to keep the Cosieve dictionary
-- tiny. I don't know if that matters.
class Cosieve p f => Foo p f where
type Index p :: *
type Index p = Fun p ()
cosieve' :: p a b -> Index p -> a -> b
default cosieve' :: (Index p ~ Fun p ()) => p a b -> Index p -> a -> b
cosieve' pab i a = cosieve pab (a <$ i)
class (Cosieve p (Corep p), Costrong p) => Corepresentable p where
type Corep p :: * -> *
type Corep p = Fun p
cotabulate :: (Corep p d -> c) -> p d c
class (Category p, Corepresentable p, Foo p (Corep p)) => Bar p where
cotabulate' :: forall d c. (Index p -> d -> c) -> p d c
default cotabulate' :: forall d c. Index p ~ Corep p () => (Index p -> d -> c) -> p d c
cotabulate' f = cotabulate (\r -> f (() <$ r) (cosieve (id :: p a a) r))
cotabulate_ :: forall d c. (d -> c) -> p d c
cotabulate_ f = cotabulate' (\ _i x -> f x)
The idea is that the non-(->) case in conjoined can use the methods that keep indices and values separate, which will be good for Indexed.
As discussed in comments on #789, it can be pretty hard to avoid space leaks and such when capturing indexed traversals. Here's one idea. There are a few ways to wiggle it, but you should get the idea.
The idea is that the non-
(->)
case inconjoined
can use the methods that keep indices and values separate, which will be good forIndexed
.