{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE QuantifiedConstraints #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE TypeFamilies #-} module Data.Profunctor.Optic.Operator ( (&) , (%) , (#) , (^.) , (^%) , (#^) , (..~) , (.~) , (**~) , (*~) , (//~) , (/~) , (%%~) , (%~) , (##~) , (#~) ) where import Data.Function import Data.Profunctor.Optic.Carrier import Data.Profunctor.Optic.Types import Data.Profunctor.Optic.Import import Data.Profunctor.Optic.Index import qualified Data.Bifunctor as B -- $setup -- >>> :set -XNoOverloadedStrings -- >>> :set -XTypeApplications -- >>> :set -XFlexibleContexts -- >>> :set -XRankNTypes -- >>> import Data.List.Index as LI -- >>> import Data.Int.Instance () -- >>> import Data.Maybe -- >>> import Data.Monoid -- >>> :load Data.Profunctor.Optic -- >>> let iat :: Int -> Ixaffine' Int [a] a; iat i = iaffine' (\s -> flip LI.ifind s $ \n _ -> n==i) (\s a -> LI.modifyAt i (const a) s) infixr 4 .~, ..~, *~, **~, /~, //~, %~, %%~, #~, ##~ infixl 8 ^., ^% infixr 8 #^ -- | View the focus of an optic. -- -- Fixity and semantics are such that subsequent field accesses can be -- performed with ('Prelude..'). -- -- >>> ("hello","world") ^. second' -- "world" -- -- >>> 5 ^. to succ -- 6 -- -- >>> import Data.Complex -- >>> ((0, 1 :+ 2), 3) ^. first' . second' . to magnitude -- 2.23606797749979 -- (^.) :: s -> AView s a -> a (^.) s o = withPrimView o id s {-# INLINE ( ^. ) #-} -- | View the focus of an indexed optic along with its index. -- -- >>> ("foo", 42) ^% ifirst -- (Just (),"foo") -- -- >>> [(0,'f'),(1,'o'),(2,'o') :: (Int, Char)] ^% iat 2 . ifirst -- (Just 2,2) -- -- In order to 'iview' a 'Choice' optic (e.g. 'Ixaffine', 'Ixtraversal', 'Ixfold', etc), -- /a/ must have a 'Monoid' instance: -- -- >>> ([] :: [Int]) ^% iat 0 -- (Nothing,0) -- -- >>> ([1] :: [Int]) ^% iat 0 -- (Just 0,1) -- (^%) :: Monoid i => s -> AIxview i s a -> (Maybe i, a) (^%) s o = withPrimView o (B.first Just) . (mempty,) $ s {-# INLINE (^%) #-} -- | Dual to '^.'. -- -- @ -- 'from' f #^ x ≡ f x -- o #^ x ≡ x '^.' 're' o -- @ -- -- This is commonly used when using a 'Prism' as a smart constructor. -- -- >>> left' #^ 4 -- Left 4 -- (#^) :: AReview t b -> b -> t o #^ b = withPrimReview o id b {-# INLINE (#^) #-} -- | Map over an optic. -- -- >>> Just 1 & just ..~ (+1) -- Just 2 -- -- >>> Nothing & just ..~ (+1) -- Nothing -- -- >>> [1,2,3] & fmapped ..~ (*10) -- [10,20,30] -- -- >>> (1,2) & first' ..~ (+1) -- (2,2) -- -- >>> (10,20) & first' ..~ show -- ("10",20) -- (..~) :: Optic (->) s t a b -> (a -> b) -> s -> t (..~) = id {-# INLINE (..~) #-} -- | Set all referenced fields to the given value. -- (.~) :: Optic (->) s t a b -> b -> s -> t (.~) o b = o (const b) {-# INLINE (.~) #-} -- | Map over a representable optic. -- (**~) :: Optic (Star f) s t a b -> (a -> f b) -> s -> f t (**~) = withStar {-# INLINE (**~) #-} -- | Set the focus of a representable optic. -- (*~) :: Optic (Star f) s t a b -> f b -> s -> f t (*~) o b = withStar o (const b) {-# INLINE (*~) #-} -- | Map over a co-representable optic. -- (//~) :: Optic (Costar f) s t a b -> (f a -> b) -> f s -> t (//~) = withCostar {-# INLINE (//~) #-} -- | Set the focus of a co-representable optic. -- (/~) :: Optic (Costar f) s t a b -> b -> f s -> t (/~) o b = withCostar o (const b) {-# INLINE (/~) #-} -- | Map over an indexed optic. -- -- See also '##~'. -- (%%~) :: Monoid i => AIxsetter i s t a b -> (i -> a -> b) -> s -> t (%%~) o f = withIxsetter o f mempty {-# INLINE (%%~) #-} -- | Set the focus of an indexed optic. -- -- See also '#~'. -- -- /Note/ if you're looking for the infix 'over' it is '..~'. -- (%~) :: Monoid i => AIxsetter i s t a b -> (i -> b) -> s -> t (%~) o = (%%~) o . (const .) {-# INLINE (%~) #-} -- | Map over a coindexed optic. -- -- Infix variant of 'kover'. -- -- See also '%%~'. -- (##~) :: Monoid k => ACxsetter k s t a b -> (k -> a -> b) -> s -> t (##~) o f = withCxsetter o f mempty {-# INLINE (##~) #-} -- | Set the focus of a coindexed optic. -- -- See also '%~'. -- (#~) :: Monoid k => ACxsetter k s t a b -> (k -> b) -> s -> t (#~) o kb = o ##~ flip (const kb) {-# INLINE (#~) #-}