{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE RankNTypes #-} module Cursor.Types where import GHC.Generics (Generic) import Data.Validity import Data.Functor.Compose import Control.Applicative import Lens.Micro data DeleteOrUpdate a = Deleted | Updated a deriving (Show, Eq, Generic) instance Validity a => Validity (DeleteOrUpdate a) instance Functor DeleteOrUpdate where fmap _ Deleted = Deleted fmap f (Updated a) = Updated (f a) instance Applicative DeleteOrUpdate where pure = Updated Deleted <*> _ = Deleted _ <*> Deleted = Deleted (Updated f) <*> (Updated a) = Updated (f a) instance Alternative DeleteOrUpdate where empty = Deleted Updated a <|> _ = Updated a Deleted <|> doua = doua joinDeletes :: Maybe (DeleteOrUpdate a) -> Maybe (DeleteOrUpdate a) -> DeleteOrUpdate a joinDeletes m1 m2 = case (m1, m2) of (Nothing, Nothing) -> Deleted (Nothing, Just a) -> a (Just a, _) -> a joinDeletes3 :: Maybe (DeleteOrUpdate a) -> Maybe (DeleteOrUpdate a) -> Maybe (DeleteOrUpdate a) -> DeleteOrUpdate a joinDeletes3 m1 m2 m3 = case (m1, m2, m3) of (Nothing, Nothing, Nothing) -> Deleted (Nothing, Nothing, Just a) -> a (Nothing, Just a, _) -> a (Just a, _, _) -> a joinPossibleDeletes :: Maybe (DeleteOrUpdate a) -> Maybe (DeleteOrUpdate a) -> Maybe (DeleteOrUpdate a) joinPossibleDeletes d1 d2 = getCompose $ Compose d1 <|> Compose d2 focusPossibleDeleteOrUpdate :: Lens' b a -> (a -> Maybe (DeleteOrUpdate a)) -> b -> Maybe (DeleteOrUpdate b) focusPossibleDeleteOrUpdate l func = getCompose . l (Compose . func)