import Data.Maybe -- | Zipper for lists data LZipper a = LZip { backward :: [a], forward :: [a] } deriving ( Eq, Show, Read ) listToZip :: [a] -> LZipper a listToZip = LZip [] zipToList :: LZipper a -> [a] zipToList (LZip [] xs) = xs zipToList (LZip (b:bs) xs) = zipToList $ LZip bs (b:xs) goForward :: LZipper a -> Maybe (LZipper a) goForward (LZip bs []) = Nothing goForward (LZip bs (x:xs)) = Just $ LZip (x:bs) xs goBackward :: LZipper a -> Maybe (LZipper a) goBackward (LZip [] xs) = Nothing goBackward (LZip (b:bs) xs) = Just $ LZip bs (b:xs) modifyLZip :: (a -> a) -> LZipper a -> LZipper a modifyLZip f z@(LZip bs []) = z modifyLZip f (LZip bs (x:xs)) = LZip bs (f x : xs) data BinTree a = BNode (BinTree a) a (BinTree a) | BEmpty deriving ( Eq, Show, Read ) data TreeDir a = TLeft a (BinTree a) | TRight (BinTree a) a deriving ( Eq, Show, Read ) -- | Zipper for binary trees data TZipper a = TZip [TreeDir a] (BinTree a) deriving ( Eq, Show, Read ) treeToZip :: BinTree a -> TZipper a treeToZip tree = TZip [] tree goLeft :: TZipper a -> Maybe (TZipper a) goLeft (TZip ds BEmpty) = Nothing goLeft (TZip ds (BNode l v r)) = Just $ TZip (TLeft v r : ds) l goRight :: TZipper a -> Maybe (TZipper a) goRight (TZip ds BEmpty) = Nothing goRight (TZip ds (BNode l v r)) = Just $ TZip (TRight l v : ds) r goUp :: TZipper a -> Maybe (TZipper a) goUp (TZip [] _) = Nothing goUp (TZip (TLeft v r : ds) tree) = Just $ TZip ds (BNode tree v r) goUp (TZip (TRight l v : ds) tree) = Just $ TZip ds (BNode l v tree) zipToTree :: TZipper a -> BinTree a zipToTree (TZip [] tree) = tree zipToTree tree = zipToTree . fromJust $ goUp tree modifyTZip :: (a -> a) -> TZipper a -> TZipper a modifyTZip f z@(TZip ds BEmpty) = z modifyTZip f (TZip ds (BNode l v r)) = TZip ds (BNode l (f v) r) testTree :: BinTree Int testTree = BNode (BNode (BNode BEmpty 4 BEmpty) 2 (BNode BEmpty 5 BEmpty)) 1 (BNode (BNode BEmpty 6 BEmpty) 3 (BNode BEmpty 7 BEmpty)) data Person = Person { eid :: Int , name :: String , surname :: String } deriving Show data Project = Project { lead :: Person , techLead :: Person } deriving Show data Team = Team { manager :: Person , job1 :: Project , job2 :: Project } deriving Show setJob1LeadID :: Team -> Int -> Team setJob1LeadID t x = t { job1 = (job1 t) { lead = (lead $ job1 t) { eid = x } } } setEid :: Int -> Person -> Person setEid neweid p = p { eid = neweid } overLead :: (Person -> Person) -> Project -> Project overLead f proj = proj { lead = f (lead proj) } overJob1 :: (Project -> Project) -> Team -> Team overJob1 f team = team { job1 = f (job1 team) } setJob1LeadID' :: Team -> Int -> Team setJob1LeadID' t x = (overJob1 . overLead . setEid) x t