planet-mitchell-0.1.0: Planet Mitchell

Optic.Setter

Contents

Synopsis

# Setter

type Setter s t a b = forall (f :: * -> *). Settable f => (a -> f b) -> s -> f t #

The only LensLike law that can apply to a Setter l is that

set l y (set l x a) ≡ set l y a


You can't view a Setter in general, so the other two laws are irrelevant.

However, two Functor laws apply to a Setter:

over l id ≡ id
over l f . over l g ≡ over l (f . g)


These can be stated more directly:

l pure ≡ pure
l f . untainted . l g ≡ l (f . untainted . g)


You can compose a Setter with a Lens or a Traversal using (.) from the Prelude and the result is always only a Setter and nothing more.

>>> over traverse f [a,b,c,d]
[f a,f b,f c,f d]

>>> over _1 f (a,b)
(f a,b)

>>> over (traverse._1) f [(a,b),(c,d)]
[(f a,b),(f c,d)]

>>> over both f (a,b)
(f a,f b)

>>> over (traverse.both) f [(a,b),(c,d)]
[(f a,f b),(f c,f d)]


type Setter' s a = Setter s s a a #

A Setter' is just a Setter that doesn't change the types.

These are particularly common when talking about monomorphic containers. e.g.

sets Data.Text.map :: Setter' Text Char

type Setter' = Simple Setter


(.~) :: ASetter s t a b -> b -> s -> t infixr 4 #

Replace the target of a Lens or all of the targets of a Setter or Traversal with a constant value.

This is an infix version of set, provided for consistency with (.=).

f <$ a ≡ mapped .~ f $ a

>>> (a,b,c,d) & _4 .~ e
(a,b,c,e)

>>> (42,"world") & _1 .~ "hello"
("hello","world")

>>> (a,b) & both .~ c
(c,c)

(.~) :: Setter s t a b    -> b -> s -> t
(.~) :: Iso s t a b       -> b -> s -> t
(.~) :: Lens s t a b      -> b -> s -> t
(.~) :: Traversal s t a b -> b -> s -> t


(%~) :: ASetter s t a b -> (a -> b) -> s -> t infixr 4 #

Modifies the target of a Lens or all of the targets of a Setter or Traversal with a user supplied function.

This is an infix version of over.

fmap f ≡ mapped %~ f
fmapDefault f ≡ traverse %~ f

>>> (a,b,c) & _3 %~ f
(a,b,f c)

>>> (a,b) & both %~ f
(f a,f b)

>>> _2 %~ length $(1,"hello") (1,5)  >>> traverse %~ f$ [a,b,c]
[f a,f b,f c]

>>> traverse %~ even $[1,2,3] [False,True,False]  >>> traverse.traverse %~ length$ [["hello","world"],["!!!"]]
[[5,5],[3]]

(%~) :: Setter s t a b    -> (a -> b) -> s -> t
(%~) :: Iso s t a b       -> (a -> b) -> s -> t
(%~) :: Lens s t a b      -> (a -> b) -> s -> t
(%~) :: Traversal s t a b -> (a -> b) -> s -> t


(+~) :: Num a => ASetter s t a a -> a -> s -> t infixr 4 #

Increment the target(s) of a numerically valued Lens, Setter or Traversal.

>>> (a,b) & _1 +~ c
(a + c,b)

>>> (a,b) & both +~ c
(a + c,b + c)

>>> (1,2) & _2 +~ 1
(1,3)

>>> [(a,b),(c,d)] & traverse.both +~ e
[(a + e,b + e),(c + e,d + e)]

(+~) :: Num a => Setter' s a    -> a -> s -> s
(+~) :: Num a => Iso' s a       -> a -> s -> s
(+~) :: Num a => Lens' s a      -> a -> s -> s
(+~) :: Num a => Traversal' s a -> a -> s -> s


(-~) :: Num a => ASetter s t a a -> a -> s -> t infixr 4 #

Decrement the target(s) of a numerically valued Lens, Iso, Setter or Traversal.

>>> (a,b) & _1 -~ c
(a - c,b)

>>> (a,b) & both -~ c
(a - c,b - c)

>>> _1 -~ 2 $(1,2) (-1,2)  >>> mapped.mapped -~ 1$ [[4,5],[6,7]]
[[3,4],[5,6]]

(-~) :: Num a => Setter' s a    -> a -> s -> s
(-~) :: Num a => Iso' s a       -> a -> s -> s
(-~) :: Num a => Lens' s a      -> a -> s -> s
(-~) :: Num a => Traversal' s a -> a -> s -> s


(*~) :: Num a => ASetter s t a a -> a -> s -> t infixr 4 #

Multiply the target(s) of a numerically valued Lens, Iso, Setter or Traversal.

>>> (a,b) & _1 *~ c
(a * c,b)

>>> (a,b) & both *~ c
(a * c,b * c)

>>> (1,2) & _2 *~ 4
(1,8)

>>> Just 24 & mapped *~ 2
Just 48

(*~) :: Num a => Setter' s a    -> a -> s -> s
(*~) :: Num a => Iso' s a       -> a -> s -> s
(*~) :: Num a => Lens' s a      -> a -> s -> s
(*~) :: Num a => Traversal' s a -> a -> s -> s


(//~) :: Fractional a => ASetter s t a a -> a -> s -> t infixr 4 #

Divide the target(s) of a numerically valued Lens, Iso, Setter or Traversal.

>>> (a,b) & _1 //~ c
(a / c,b)

>>> (a,b) & both //~ c
(a / c,b / c)

>>> ("Hawaii",10) & _2 //~ 2
("Hawaii",5.0)

(//~) :: Fractional a => Setter' s a    -> a -> s -> s
(//~) :: Fractional a => Iso' s a       -> a -> s -> s
(//~) :: Fractional a => Lens' s a      -> a -> s -> s
(//~) :: Fractional a => Traversal' s a -> a -> s -> s


(^~) :: (Num a, Integral e) => ASetter s t a a -> e -> s -> t infixr 4 #

Raise the target(s) of a numerically valued Lens, Setter or Traversal to a non-negative integral power.

>>> (1,3) & _2 ^~ 2
(1,9)

(^~) :: (Num a, Integral e) => Setter' s a    -> e -> s -> s
(^~) :: (Num a, Integral e) => Iso' s a       -> e -> s -> s
(^~) :: (Num a, Integral e) => Lens' s a      -> e -> s -> s
(^~) :: (Num a, Integral e) => Traversal' s a -> e -> s -> s


(^^~) :: (Fractional a, Integral e) => ASetter s t a a -> e -> s -> t infixr 4 #

Raise the target(s) of a fractionally valued Lens, Setter or Traversal to an integral power.

>>> (1,2) & _2 ^^~ (-1)
(1,0.5)

(^^~) :: (Fractional a, Integral e) => Setter' s a    -> e -> s -> s
(^^~) :: (Fractional a, Integral e) => Iso' s a       -> e -> s -> s
(^^~) :: (Fractional a, Integral e) => Lens' s a      -> e -> s -> s
(^^~) :: (Fractional a, Integral e) => Traversal' s a -> e -> s -> s


(**~) :: Floating a => ASetter s t a a -> a -> s -> t infixr 4 #

Raise the target(s) of a floating-point valued Lens, Setter or Traversal to an arbitrary power.

>>> (a,b) & _1 **~ c
(a**c,b)

>>> (a,b) & both **~ c
(a**c,b**c)

>>> _2 **~ 10 $(3,2) (3,1024.0)  (**~) :: Floating a => Setter' s a -> a -> s -> s (**~) :: Floating a => Iso' s a -> a -> s -> s (**~) :: Floating a => Lens' s a -> a -> s -> s (**~) :: Floating a => Traversal' s a -> a -> s -> s  (||~) :: ASetter s t Bool Bool -> Bool -> s -> t infixr 4 # Logically || the target(s) of a Bool-valued Lens or Setter. >>> both ||~ True$ (False,True)
(True,True)

>>> both ||~ False $(False,True) (False,True)  (||~) :: Setter' s Bool -> Bool -> s -> s (||~) :: Iso' s Bool -> Bool -> s -> s (||~) :: Lens' s Bool -> Bool -> s -> s (||~) :: Traversal' s Bool -> Bool -> s -> s  (&&~) :: ASetter s t Bool Bool -> Bool -> s -> t infixr 4 # Logically && the target(s) of a Bool-valued Lens or Setter. >>> both &&~ True$ (False, True)
(False,True)

>>> both &&~ False $(False, True) (False,False)  (&&~) :: Setter' s Bool -> Bool -> s -> s (&&~) :: Iso' s Bool -> Bool -> s -> s (&&~) :: Lens' s Bool -> Bool -> s -> s (&&~) :: Traversal' s Bool -> Bool -> s -> s  set :: ASetter s t a b -> b -> s -> t # Replace the target of a Lens or all of the targets of a Setter or Traversal with a constant value. (<$) ≡ set mapped

>>> set _2 "hello" (1,())
(1,"hello")

>>> set mapped () [1,2,3,4]
[(),(),(),()]


Note: Attempting to set a Fold or Getter will fail at compile time with an relatively nice error message.

set :: Setter s t a b    -> b -> s -> t
set :: Iso s t a b       -> b -> s -> t
set :: Lens s t a b      -> b -> s -> t
set :: Traversal s t a b -> b -> s -> t


over :: ASetter s t a b -> (a -> b) -> s -> t #

Modify the target of a Lens or all the targets of a Setter or Traversal with a function.

fmap ≡ over mapped
fmapDefault ≡ over traverse
sets . over ≡ id
over . sets ≡ id


Given any valid Setter l, you can also rely on the law:

over l f . over l g = over l (f . g)


e.g.

>>> over mapped f (over mapped g [a,b,c]) == over mapped (f . g) [a,b,c]
True


Another way to view over is to say that it transforms a Setter into a "semantic editor combinator".

>>> over mapped f (Just a)
Just (f a)

>>> over mapped (*10) [1,2,3]
[10,20,30]

>>> over _1 f (a,b)
(f a,b)

>>> over _1 show (10,20)
("10",20)

over :: Setter s t a b -> (a -> b) -> s -> t
over :: ASetter s t a b -> (a -> b) -> s -> t