module Generics.MultiRec.Transformations.ZipChildren where
import Generics.MultiRec hiding ( show, foldM )
import Control.Monad.State hiding ( foldM, mapM )
import Data.Foldable ( toList )
import Generics.MultiRec.CountIs
import Generics.MultiRec.Transformations.Path
import Generics.MultiRec.Transformations.Children
import Generics.MultiRec.Transformations.MemoTable
zipChildrenM :: (Monad m, Fam phi, ZipChildren phi (PF phi))
=> phi ix
-> (forall t. (Lookup phi (Ixs phi) t, Children phi (PF phi) t, GetChildrenTable phi (Ixs phi) t, Eq t) => phi t -> Path phi t ix -> t -> t -> m a)
-> ix
-> ix
-> m [a]
zipChildrenM p f a b = zipChildren p (\p w (I0 l) (I0 r) -> f p w l r)
(\z -> Push (error "oops") z Empty)
(from p a) (from p b)
class ZipChildren phi (f :: (* -> *) -> * -> *) where
zipChildren :: (Monad m)
=> phi ix
-> (forall t. (Lookup phi (Ixs phi) t, Children phi (PF phi) t, GetChildrenTable phi (Ixs phi) t, Eq t)
=> phi t -> Path phi t ix -> r t -> r t -> m a)
-> (forall t. Dir f t ix -> Path phi t ix)
-> f r ix
-> f r ix
-> m [a]
instance ( Lookup phi (Ixs phi) xi, El phi xi, Children phi (PF phi) xi
, GetChildrenTable phi (Ixs phi) xi, Eq xi) => ZipChildren phi (I xi) where
zipChildren _ f w (I l) (I r) = f proof (w CId) l r >>= \x -> return [x]
instance ZipChildren phi (K a) where
zipChildren _ _ _ _ _ = return []
instance ZipChildren phi U where
zipChildren _ _ _ _ _ = return []
instance (ZipChildren phi f, ZipChildren phi g) => ZipChildren phi (f :+: g) where
zipChildren p f w (L l) (L r) = zipChildren p f (w . CL) l r
zipChildren p f w (R l) (R r) = zipChildren p f (w . CR) l r
instance (ZipChildren phi f, ZipChildren phi g, CountIs g)
=> ZipChildren phi (f :*: g) where
zipChildren p f w (l1 :*: l2) (r1 :*: r2) =
liftM2 (++) (zipChildren p f (\z -> w (C1 z nullY)) l1 r1)
(zipChildren p f (\z -> w (C2 nullX z)) l2 r2)
where nullX = error "nullX"
nullY = error "nullY"
instance (ZipChildren phi f, Constructor c) => ZipChildren phi (C c f) where
zipChildren p f w (C l) (C r) = zipChildren p f (w . CC) l r
instance ZipChildren phi f => ZipChildren phi (f :>: ix) where
zipChildren p f w (Tag l) (Tag r) = zipChildren p f (w . CTag) l r
instance (ZipChildren phi f) => ZipChildren phi (Maybe :.: f) where
zipChildren p f w (D l) (D r) = liftM concat $ sequence $
zipWith3 (\i -> zipChildren p f (w . CCM))
[0..] (toList l) (toList r)
instance (ZipChildren phi f) => ZipChildren phi ([] :.: f) where
zipChildren p f w (D l) (D r) = liftM concat $ sequence $
zipWith3 (\i -> zipChildren p f (\x -> w (CCL (ll i) x lr)))
[0..] l r
where ll i = replicate i (error "oops3")
lr = error "oops2"