module Data.Extensible.Product where
import Control.Lens(Lens', lens)
data (a :&: b) = Prod a b deriving Show
class ProductClass c s where
grab :: c -> s
stash :: s -> c -> c
type (c :>&: a) = (ProductClass c a)
prodLens :: (c :>&: a) => Lens' c a
prodLens = lens grab (flip stash)
(<&) :: a -> b -> a :&: b
(<&) = Prod
instance ProductClass a a where
grab = id
stash x _ = x
instance ProductClass (a :&: b) b where
grab (Prod x y) = y
stash y (Prod xx yy) = Prod xx y
instance ProductClass c a => ProductClass (c :&: b) a where
grab (Prod x y) = grab x
stash x (Prod xx yy) = Prod (stash x xx) yy
instance ProductClass (a,b) a where
grab = fst
stash x (_, y) = (x, y)
instance ProductClass (a,b) b where
grab = snd
stash y (x, _) = (x, y)
instance ProductClass (a,b,c) a where
grab (a, _, _) = a
stash a (_, b, c) = (a,b,c)
instance ProductClass (a,b,c) b where
grab (_, b, _) = b
stash b (a, _, c) = (a,b,c)
instance ProductClass (a,b,c) c where
grab (_, _, c) = c
stash c (a, b, _) = (a,b,c)
instance ProductClass (a,b,c,d) a where
grab (a, _, _, _) = a
stash a (_, b, c, d) = (a,b,c,d)
instance ProductClass (a,b,c,d) b where
grab (_, b, _, _) = b
stash b (a, _, c,d) = (a,b,c,d)
instance ProductClass (a,b,c,d) c where
grab (_, _, c, _) = c
stash c (a, b, _, d) = (a,b,c,d)
instance ProductClass (a,b,c,d) d where
grab (_, _, _, d) = d
stash d (a, b, c, _) = (a,b,c,d)
instance ProductClass (a,b,c,d,e) a where
grab (a, _, _, _,_) = a
stash a (_, b, c, d,e) = (a,b,c,d,e)
instance ProductClass (a,b,c,d,e) b where
grab (_, b, _, _,_) = b
stash b (a, _, c,d,e) = (a,b,c,d,e)
instance ProductClass (a,b,c,d,e) c where
grab (_, _, c, _,_) = c
stash c (a, b, _, d,e) = (a,b,c,d,e)
instance ProductClass (a,b,c,d,e) d where
grab (_, _, _, d,_) = d
stash d (a, b, c, _,e) = (a,b,c,d,e)
instance ProductClass (a,b,c,d,e) e where
grab (_, _, _, _, e) = e
stash e (a, b, c, d,_) = (a,b,c,d,e)