module Pandora.Paradigm.Inventory.Optics
(Lens, type (:-.), (|>), view, set, over, (^.), (.~), (%~)) where
import Pandora.Core.Morphism ((.), ($))
import Pandora.Paradigm.Inventory.Storage (Storage, access, position, retrofit)
import Pandora.Pattern.Functor.Covariant (Covariant ((<$)))
import Pandora.Pattern.Functor.Extractable (Extractable (extract))
infixr 0 :-.
type (:-.) src tgt = Lens src tgt
type Lens src tgt = src -> Storage tgt src
(|>) :: Lens src btw -> Lens btw tgt -> Lens src tgt
from |> to = \x -> ((<$) x . to) . position . from $ x
view :: Lens src tgt -> src -> tgt
view lens = position . lens
(^.) :: Lens src tgt -> src -> tgt
(^.) = view
set :: Lens src tgt -> tgt -> src -> src
set lens new = access new . lens
(.~) :: Lens src tgt -> tgt -> src -> src
lens .~ new = set lens new
over :: Lens src tgt -> (tgt -> tgt) -> src -> src
over lens f = extract . retrofit f . lens
(%~) :: Lens src tgt -> (tgt -> tgt) -> src -> src
lens %~ f = over lens f