module LoopCompF(loopCompF,loopCompSP,loopThroughBothF,loopThroughBothSP) where
import Fudget        
import CompFfun(prepostMapHigh)
import CompF(compF)
import CompSP(compSP,prepostMapSP)
import Loop(loopLeftSP)
import Loops(loopLeftF)

-- loopComp = symmetric version of loopThroughRight

loopCompF :: F (Either (Either r2l inl) (Either l2r inr))
               (Either (Either l2r outl) (Either r2l outr)) ->
	     F (Either inl inr) (Either outl outr)
loopCompF :: forall r2l inl l2r inr outl outr.
F (Either (Either r2l inl) (Either l2r inr))
  (Either (Either l2r outl) (Either r2l outr))
-> F (Either inl inr) (Either outl outr)
loopCompF = forall a b c. F (Either a b) (Either a c) -> F b c
loopLeftF forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {hi} {b} {c} {ho}.
(hi -> b) -> (c -> ho) -> F b c -> F hi ho
prepostMapHigh forall {a} {a} {b} {b}.
Either (Either a a) (Either b b)
-> Either (Either a b) (Either a b)
pre forall {a} {a} {b} {b}.
Either (Either a a) (Either b b)
-> Either (Either a b) (Either a b)
post

loopThroughBothF :: F (Either r2l inl) (Either l2r outl)
-> F (Either l2r inr) (Either r2l outr)
-> F (Either inl inr) (Either outl outr)
loopThroughBothF F (Either r2l inl) (Either l2r outl)
fud1 F (Either l2r inr) (Either r2l outr)
fud2 = forall r2l inl l2r inr outl outr.
F (Either (Either r2l inl) (Either l2r inr))
  (Either (Either l2r outl) (Either r2l outr))
-> F (Either inl inr) (Either outl outr)
loopCompF (F (Either r2l inl) (Either l2r outl)
fud1 forall {a} {b} {c} {d}.
F a b -> F c d -> F (Either a c) (Either b d)
`compF` F (Either l2r inr) (Either r2l outr)
fud2)
loopThroughBothSP :: SP (Either a b) (Either a a)
-> SP (Either a b) (Either a b) -> SP (Either b b) (Either a b)
loopThroughBothSP SP (Either a b) (Either a a)
sp1 SP (Either a b) (Either a b)
sp2 = forall {a} {b} {a} {b} {a} {b}.
SP
  (Either (Either a b) (Either a b))
  (Either (Either a a) (Either a b))
-> SP (Either b b) (Either a b)
loopCompSP (SP (Either a b) (Either a a)
sp1 forall {a1} {a2} {a3} {b}.
SP a1 a2 -> SP a3 b -> SP (Either a1 a3) (Either a2 b)
`compSP` SP (Either a b) (Either a b)
sp2)

loopCompSP :: SP
  (Either (Either a b) (Either a b))
  (Either (Either a a) (Either a b))
-> SP (Either b b) (Either a b)
loopCompSP = forall {a} {b1} {b2}. SP (Either a b1) (Either a b2) -> SP b1 b2
loopLeftSP forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {t1} {a} {t2} {b}.
(t1 -> a) -> (t2 -> b) -> SP a t2 -> SP t1 b
prepostMapSP forall {a} {a} {b} {b}.
Either (Either a a) (Either b b)
-> Either (Either a b) (Either a b)
pre forall {a} {a} {b} {b}.
Either (Either a a) (Either b b)
-> Either (Either a b) (Either a b)
post

post :: Either (Either a a) (Either b b)
-> Either (Either a b) (Either a b)
post (Left  (Left  a
x)) = forall a b. a -> Either a b
Left (forall a b. a -> Either a b
Left a
x)
post (Left  (Right a
x)) = forall a b. b -> Either a b
Right (forall a b. a -> Either a b
Left a
x)
post (Right (Left b
x)) = forall a b. a -> Either a b
Left (forall a b. b -> Either a b
Right b
x)
post (Right (Right b
x)) = forall a b. b -> Either a b
Right (forall a b. b -> Either a b
Right b
x)
-- post = either (either (Left.Left) (Right.Left))  (either (Left.Right) (Right.Right))

pre :: Either (Either a a) (Either b b)
-> Either (Either a b) (Either a b)
pre (Right (Left b
x)) = forall a b. a -> Either a b
Left (forall a b. b -> Either a b
Right b
x)
pre (Right (Right b
x)) = forall a b. b -> Either a b
Right (forall a b. b -> Either a b
Right b
x)
pre (Left (Left a
x)) = forall a b. b -> Either a b
Right (forall a b. a -> Either a b
Left a
x)
pre (Left (Right a
x)) = forall a b. a -> Either a b
Left (forall a b. a -> Either a b
Left a
x)