1{-# LANGUAGE CPP #-} 2{-# LANGUAGE GADTs #-} 3{-# LANGUAGE Rank2Types #-} 4{-# LANGUAGE FlexibleContexts #-} 5{-# LANGUAGE FlexibleInstances #-} 6{-# LANGUAGE ScopedTypeVariables #-} 7{-# LANGUAGE MultiParamTypeClasses #-} 8{-# LANGUAGE KindSignatures #-} 9#if __GLASGOW_HASKELL__ >= 706 10{-# LANGUAGE PolyKinds #-} 11#endif 12#if __GLASGOW_HASKELL__ >= 800 13{-# LANGUAGE TypeInType #-} 14#endif 15{-# LANGUAGE Trustworthy #-} 16------------------------------------------------------------------------------- 17-- | 18-- Module : Control.Lens.Type 19-- Copyright : (C) 2012-16 Edward Kmett 20-- License : BSD-style (see the file LICENSE) 21-- Maintainer : Edward Kmett <ekmett@gmail.com> 22-- Stability : provisional 23-- Portability : Rank2Types 24-- 25-- This module exports the majority of the types that need to appear in user 26-- signatures or in documentation when talking about lenses. The remaining types 27-- for consuming lenses are distributed across various modules in the hierarchy. 28------------------------------------------------------------------------------- 29module Control.Lens.Type 30 ( 31 -- * Other 32 Equality, Equality', As 33 , Iso, Iso' 34 , Prism , Prism' 35 , Review , AReview 36 -- * Lenses, Folds and Traversals 37 , Lens, Lens' 38 , Traversal, Traversal' 39 , Traversal1, Traversal1' 40 , Setter, Setter' 41 , Getter, Fold 42 , Fold1 43 -- * Indexed 44 , IndexedLens, IndexedLens' 45 , IndexedTraversal, IndexedTraversal' 46 , IndexedTraversal1, IndexedTraversal1' 47 , IndexedSetter, IndexedSetter' 48 , IndexedGetter, IndexedFold 49 , IndexedFold1 50 -- * Index-Preserving 51 , IndexPreservingLens, IndexPreservingLens' 52 , IndexPreservingTraversal, IndexPreservingTraversal' 53 , IndexPreservingTraversal1, IndexPreservingTraversal1' 54 , IndexPreservingSetter, IndexPreservingSetter' 55 , IndexPreservingGetter, IndexPreservingFold 56 , IndexPreservingFold1 57 -- * Common 58 , Simple 59 , LensLike, LensLike' 60 , Over, Over' 61 , IndexedLensLike, IndexedLensLike' 62 , Optical, Optical' 63 , Optic, Optic' 64 ) where 65 66import Prelude () 67 68import Control.Lens.Internal.Prelude 69import Control.Lens.Internal.Setter 70import Control.Lens.Internal.Indexed 71import Data.Bifunctor 72import Data.Functor.Apply 73#if __GLASGOW_HASKELL__ >= 800 74import Data.Kind 75#endif 76 77-- $setup 78-- >>> :set -XNoOverloadedStrings 79-- >>> import Control.Lens 80-- >>> import Debug.SimpleReflect.Expr 81-- >>> import Debug.SimpleReflect.Vars as Vars hiding (f,g,h) 82-- >>> let f :: Expr -> Expr; f = Debug.SimpleReflect.Vars.f 83-- >>> let g :: Expr -> Expr; g = Debug.SimpleReflect.Vars.g 84-- >>> let h :: Expr -> Expr -> Expr; h = Debug.SimpleReflect.Vars.h 85-- >>> let getter :: Expr -> Expr; getter = fun "getter" 86-- >>> let setter :: Expr -> Expr -> Expr; setter = fun "setter" 87-- >>> import Numeric.Natural 88-- >>> let nat :: Prism' Integer Natural; nat = prism toInteger $ \i -> if i < 0 then Left i else Right (fromInteger i) 89 90------------------------------------------------------------------------------- 91-- Lenses 92------------------------------------------------------------------------------- 93 94-- | A 'Lens' is actually a lens family as described in 95-- <http://comonad.com/reader/2012/mirrored-lenses/>. 96-- 97-- With great power comes great responsibility and a 'Lens' is subject to the 98-- three common sense 'Lens' laws: 99-- 100-- 1) You get back what you put in: 101-- 102-- @ 103-- 'Control.Lens.Getter.view' l ('Control.Lens.Setter.set' l v s) ≡ v 104-- @ 105-- 106-- 2) Putting back what you got doesn't change anything: 107-- 108-- @ 109-- 'Control.Lens.Setter.set' l ('Control.Lens.Getter.view' l s) s ≡ s 110-- @ 111-- 112-- 3) Setting twice is the same as setting once: 113-- 114-- @ 115-- 'Control.Lens.Setter.set' l v' ('Control.Lens.Setter.set' l v s) ≡ 'Control.Lens.Setter.set' l v' s 116-- @ 117-- 118-- These laws are strong enough that the 4 type parameters of a 'Lens' cannot 119-- vary fully independently. For more on how they interact, read the \"Why is 120-- it a Lens Family?\" section of 121-- <http://comonad.com/reader/2012/mirrored-lenses/>. 122-- 123-- There are some emergent properties of these laws: 124-- 125-- 1) @'Control.Lens.Setter.set' l s@ must be injective for every @s@ This is a consequence of law #1 126-- 127-- 2) @'Control.Lens.Setter.set' l@ must be surjective, because of law #2, which indicates that it is possible to obtain any 'v' from some 's' such that @'Control.Lens.Setter.set' s v = s@ 128-- 129-- 3) Given just the first two laws you can prove a weaker form of law #3 where the values @v@ that you are setting match: 130-- 131-- @ 132-- 'Control.Lens.Setter.set' l v ('Control.Lens.Setter.set' l v s) ≡ 'Control.Lens.Setter.set' l v s 133-- @ 134-- 135-- Every 'Lens' can be used directly as a 'Control.Lens.Setter.Setter' or 'Traversal'. 136-- 137-- You can also use a 'Lens' for 'Control.Lens.Getter.Getting' as if it were a 138-- 'Fold' or 'Getter'. 139-- 140-- Since every 'Lens' is a valid 'Traversal', the 141-- 'Traversal' laws are required of any 'Lens' you create: 142-- 143-- @ 144-- l 'pure' ≡ 'pure' 145-- 'fmap' (l f) '.' l g ≡ 'Data.Functor.Compose.getCompose' '.' l ('Data.Functor.Compose.Compose' '.' 'fmap' f '.' g) 146-- @ 147-- 148-- @ 149-- type 'Lens' s t a b = forall f. 'Functor' f => 'LensLike' f s t a b 150-- @ 151type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t 152 153-- | @ 154-- type 'Lens'' = 'Simple' 'Lens' 155-- @ 156type Lens' s a = Lens s s a a 157 158-- | Every 'IndexedLens' is a valid 'Lens' and a valid 'Control.Lens.Traversal.IndexedTraversal'. 159type IndexedLens i s t a b = forall f p. (Indexable i p, Functor f) => p a (f b) -> s -> f t 160 161-- | @ 162-- type 'IndexedLens'' i = 'Simple' ('IndexedLens' i) 163-- @ 164type IndexedLens' i s a = IndexedLens i s s a a 165 166-- | An 'IndexPreservingLens' leaves any index it is composed with alone. 167type IndexPreservingLens s t a b = forall p f. (Conjoined p, Functor f) => p a (f b) -> p s (f t) 168 169-- | @ 170-- type 'IndexPreservingLens'' = 'Simple' 'IndexPreservingLens' 171-- @ 172type IndexPreservingLens' s a = IndexPreservingLens s s a a 173 174------------------------------------------------------------------------------ 175-- Traversals 176------------------------------------------------------------------------------ 177 178-- | A 'Traversal' can be used directly as a 'Control.Lens.Setter.Setter' or a 'Fold' (but not as a 'Lens') and provides 179-- the ability to both read and update multiple fields, subject to some relatively weak 'Traversal' laws. 180-- 181-- These have also been known as multilenses, but they have the signature and spirit of 182-- 183-- @ 184-- 'Data.Traversable.traverse' :: 'Data.Traversable.Traversable' f => 'Traversal' (f a) (f b) a b 185-- @ 186-- 187-- and the more evocative name suggests their application. 188-- 189-- Most of the time the 'Traversal' you will want to use is just 'Data.Traversable.traverse', but you can also pass any 190-- 'Lens' or 'Iso' as a 'Traversal', and composition of a 'Traversal' (or 'Lens' or 'Iso') with a 'Traversal' (or 'Lens' or 'Iso') 191-- using ('.') forms a valid 'Traversal'. 192-- 193-- The laws for a 'Traversal' @t@ follow from the laws for 'Data.Traversable.Traversable' as stated in \"The Essence of the Iterator Pattern\". 194-- 195-- @ 196-- t 'pure' ≡ 'pure' 197-- 'fmap' (t f) '.' t g ≡ 'Data.Functor.Compose.getCompose' '.' t ('Data.Functor.Compose.Compose' '.' 'fmap' f '.' g) 198-- @ 199-- 200-- One consequence of this requirement is that a 'Traversal' needs to leave the same number of elements as a 201-- candidate for subsequent 'Traversal' that it started with. Another testament to the strength of these laws 202-- is that the caveat expressed in section 5.5 of the \"Essence of the Iterator Pattern\" about exotic 203-- 'Data.Traversable.Traversable' instances that 'Data.Traversable.traverse' the same entry multiple times was actually already ruled out by the 204-- second law in that same paper! 205type Traversal s t a b = forall f. Applicative f => (a -> f b) -> s -> f t 206 207-- | @ 208-- type 'Traversal'' = 'Simple' 'Traversal' 209-- @ 210type Traversal' s a = Traversal s s a a 211 212type Traversal1 s t a b = forall f. Apply f => (a -> f b) -> s -> f t 213type Traversal1' s a = Traversal1 s s a a 214 215-- | Every 'IndexedTraversal' is a valid 'Control.Lens.Traversal.Traversal' or 216-- 'Control.Lens.Fold.IndexedFold'. 217-- 218-- The 'Indexed' constraint is used to allow an 'IndexedTraversal' to be used 219-- directly as a 'Control.Lens.Traversal.Traversal'. 220-- 221-- The 'Control.Lens.Traversal.Traversal' laws are still required to hold. 222-- 223-- In addition, the index @i@ should satisfy the requirement that it stays 224-- unchanged even when modifying the value @a@, otherwise traversals like 225-- 'indices' break the 'Traversal' laws. 226type IndexedTraversal i s t a b = forall p f. (Indexable i p, Applicative f) => p a (f b) -> s -> f t 227 228-- | @ 229-- type 'IndexedTraversal'' i = 'Simple' ('IndexedTraversal' i) 230-- @ 231type IndexedTraversal' i s a = IndexedTraversal i s s a a 232 233type IndexedTraversal1 i s t a b = forall p f. (Indexable i p, Apply f) => p a (f b) -> s -> f t 234type IndexedTraversal1' i s a = IndexedTraversal1 i s s a a 235 236-- | An 'IndexPreservingLens' leaves any index it is composed with alone. 237type IndexPreservingTraversal s t a b = forall p f. (Conjoined p, Applicative f) => p a (f b) -> p s (f t) 238 239-- | @ 240-- type 'IndexPreservingTraversal'' = 'Simple' 'IndexPreservingTraversal' 241-- @ 242type IndexPreservingTraversal' s a = IndexPreservingTraversal s s a a 243 244type IndexPreservingTraversal1 s t a b = forall p f. (Conjoined p, Apply f) => p a (f b) -> p s (f t) 245type IndexPreservingTraversal1' s a = IndexPreservingTraversal1 s s a a 246 247------------------------------------------------------------------------------ 248-- Setters 249------------------------------------------------------------------------------ 250 251-- | The only 'LensLike' law that can apply to a 'Setter' @l@ is that 252-- 253-- @ 254-- 'Control.Lens.Setter.set' l y ('Control.Lens.Setter.set' l x a) ≡ 'Control.Lens.Setter.set' l y a 255-- @ 256-- 257-- You can't 'Control.Lens.Getter.view' a 'Setter' in general, so the other two laws are irrelevant. 258-- 259-- However, two 'Functor' laws apply to a 'Setter': 260-- 261-- @ 262-- 'Control.Lens.Setter.over' l 'id' ≡ 'id' 263-- 'Control.Lens.Setter.over' l f '.' 'Control.Lens.Setter.over' l g ≡ 'Control.Lens.Setter.over' l (f '.' g) 264-- @ 265-- 266-- These can be stated more directly: 267-- 268-- @ 269-- l 'pure' ≡ 'pure' 270-- l f '.' 'untainted' '.' l g ≡ l (f '.' 'untainted' '.' g) 271-- @ 272-- 273-- You can compose a 'Setter' with a 'Lens' or a 'Traversal' using ('.') from the @Prelude@ 274-- and the result is always only a 'Setter' and nothing more. 275-- 276-- >>> over traverse f [a,b,c,d] 277-- [f a,f b,f c,f d] 278-- 279-- >>> over _1 f (a,b) 280-- (f a,b) 281-- 282-- >>> over (traverse._1) f [(a,b),(c,d)] 283-- [(f a,b),(f c,d)] 284-- 285-- >>> over both f (a,b) 286-- (f a,f b) 287-- 288-- >>> over (traverse.both) f [(a,b),(c,d)] 289-- [(f a,f b),(f c,f d)] 290type Setter s t a b = forall f. Settable f => (a -> f b) -> s -> f t 291 292-- | A 'Setter'' is just a 'Setter' that doesn't change the types. 293-- 294-- These are particularly common when talking about monomorphic containers. /e.g./ 295-- 296-- @ 297-- 'sets' Data.Text.map :: 'Setter'' 'Data.Text.Internal.Text' 'Char' 298-- @ 299-- 300-- @ 301-- type 'Setter'' = 'Simple' 'Setter' 302-- @ 303type Setter' s a = Setter s s a a 304 305-- | Every 'IndexedSetter' is a valid 'Setter'. 306-- 307-- The 'Setter' laws are still required to hold. 308type IndexedSetter i s t a b = forall f p. 309 (Indexable i p, Settable f) => p a (f b) -> s -> f t 310 311-- | @ 312-- type 'IndexedSetter'' i = 'Simple' ('IndexedSetter' i) 313-- @ 314type IndexedSetter' i s a = IndexedSetter i s s a a 315 316-- | An 'IndexPreservingSetter' can be composed with a 'IndexedSetter', 'IndexedTraversal' or 'IndexedLens' 317-- and leaves the index intact, yielding an 'IndexedSetter'. 318type IndexPreservingSetter s t a b = forall p f. (Conjoined p, Settable f) => p a (f b) -> p s (f t) 319 320-- | @ 321-- type 'IndexedPreservingSetter'' i = 'Simple' 'IndexedPreservingSetter' 322-- @ 323type IndexPreservingSetter' s a = IndexPreservingSetter s s a a 324 325----------------------------------------------------------------------------- 326-- Isomorphisms 327----------------------------------------------------------------------------- 328 329-- | Isomorphism families can be composed with another 'Lens' using ('.') and 'id'. 330-- 331-- Since every 'Iso' is both a valid 'Lens' and a valid 'Prism', the laws for those types 332-- imply the following laws for an 'Iso' 'f': 333-- 334-- @ 335-- f '.' 'Control.Lens.Iso.from' f ≡ 'id' 336-- 'Control.Lens.Iso.from' f '.' f ≡ 'id' 337-- @ 338-- 339-- Note: Composition with an 'Iso' is index- and measure- preserving. 340type Iso s t a b = forall p f. (Profunctor p, Functor f) => p a (f b) -> p s (f t) 341 342-- | @ 343-- type 'Iso'' = 'Control.Lens.Type.Simple' 'Iso' 344-- @ 345type Iso' s a = Iso s s a a 346 347------------------------------------------------------------------------------ 348-- Review Internals 349------------------------------------------------------------------------------ 350 351-- | This is a limited form of a 'Prism' that can only be used for 're' operations. 352-- 353-- Like with a 'Getter', there are no laws to state for a 'Review'. 354-- 355-- You can generate a 'Review' by using 'unto'. You can also use any 'Prism' or 'Iso' 356-- directly as a 'Review'. 357type Review t b = forall p f. (Choice p, Bifunctor p, Settable f) => Optic' p f t b 358 359-- | If you see this in a signature for a function, the function is expecting a 'Review' 360-- (in practice, this usually means a 'Prism'). 361type AReview t b = Optic' Tagged Identity t b 362 363------------------------------------------------------------------------------ 364-- Prism Internals 365------------------------------------------------------------------------------ 366 367-- | A 'Prism' @l@ is a 'Traversal' that can also be turned 368-- around with 'Control.Lens.Review.re' to obtain a 'Getter' in the 369-- opposite direction. 370-- 371-- There are three laws that a 'Prism' should satisfy: 372-- 373-- First, if I 'Control.Lens.Review.re' or 'Control.Lens.Review.review' a value with a 'Prism' and then 'Control.Lens.Fold.preview' or use ('Control.Lens.Fold.^?'), I will get it back: 374-- 375-- @ 376-- 'Control.Lens.Fold.preview' l ('Control.Lens.Review.review' l b) ≡ 'Just' b 377-- @ 378-- 379-- Second, if you can extract a value @a@ using a 'Prism' @l@ from a value @s@, then the value @s@ is completely described by @l@ and @a@: 380-- 381-- @ 382-- 'Control.Lens.Fold.preview' l s ≡ 'Just' a ⟹ 'Control.Lens.Review.review' l a ≡ s 383-- @ 384-- 385-- Third, if you get non-match @t@, you can convert it result back to @s@: 386-- 387-- @ 388-- 'Control.Lens.Combinators.matching' l s ≡ 'Left' t ⟹ 'Control.Lens.Combinators.matching' l t ≡ 'Left' s 389-- @ 390-- 391-- The first two laws imply that the 'Traversal' laws hold for every 'Prism' and that we 'Data.Traversable.traverse' at most 1 element: 392-- 393-- @ 394-- 'Control.Lens.Fold.lengthOf' l x '<=' 1 395-- @ 396-- 397-- It may help to think of this as an 'Iso' that can be partial in one direction. 398-- 399-- Every 'Prism' is a valid 'Traversal'. 400-- 401-- Every 'Iso' is a valid 'Prism'. 402-- 403-- For example, you might have a @'Prism'' 'Integer' 'Numeric.Natural.Natural'@ allows you to always 404-- go from a 'Numeric.Natural.Natural' to an 'Integer', and provide you with tools to check if an 'Integer' is 405-- a 'Numeric.Natural.Natural' and/or to edit one if it is. 406-- 407-- 408-- @ 409-- 'nat' :: 'Prism'' 'Integer' 'Numeric.Natural.Natural' 410-- 'nat' = 'Control.Lens.Prism.prism' 'toInteger' '$' \\ i -> 411-- if i '<' 0 412-- then 'Left' i 413-- else 'Right' ('fromInteger' i) 414-- @ 415-- 416-- Now we can ask if an 'Integer' is a 'Numeric.Natural.Natural'. 417-- 418-- >>> 5^?nat 419-- Just 5 420-- 421-- >>> (-5)^?nat 422-- Nothing 423-- 424-- We can update the ones that are: 425-- 426-- >>> (-3,4) & both.nat *~ 2 427-- (-3,8) 428-- 429-- And we can then convert from a 'Numeric.Natural.Natural' to an 'Integer'. 430-- 431-- >>> 5 ^. re nat -- :: Natural 432-- 5 433-- 434-- Similarly we can use a 'Prism' to 'Data.Traversable.traverse' the 'Left' half of an 'Either': 435-- 436-- >>> Left "hello" & _Left %~ length 437-- Left 5 438-- 439-- or to construct an 'Either': 440-- 441-- >>> 5^.re _Left 442-- Left 5 443-- 444-- such that if you query it with the 'Prism', you will get your original input back. 445-- 446-- >>> 5^.re _Left ^? _Left 447-- Just 5 448-- 449-- Another interesting way to think of a 'Prism' is as the categorical dual of a 'Lens' 450-- -- a co-'Lens', so to speak. This is what permits the construction of 'Control.Lens.Prism.outside'. 451-- 452-- Note: Composition with a 'Prism' is index-preserving. 453type Prism s t a b = forall p f. (Choice p, Applicative f) => p a (f b) -> p s (f t) 454 455-- | A 'Simple' 'Prism'. 456type Prism' s a = Prism s s a a 457 458------------------------------------------------------------------------------- 459-- Equality 460------------------------------------------------------------------------------- 461 462-- | A witness that @(a ~ s, b ~ t)@. 463-- 464-- Note: Composition with an 'Equality' is index-preserving. 465#if __GLASGOW_HASKELL__ >= 800 466type Equality (s :: k1) (t :: k2) (a :: k1) (b :: k2) = forall k3 (p :: k1 -> k3 -> Type) (f :: k2 -> k3) . 467#elif __GLASGOW_HASKELL__ >= 706 468type Equality (s :: k1) (t :: k2) (a :: k1) (b :: k2) = forall (p :: k1 -> * -> *) (f :: k2 -> *) . 469#else 470type Equality s t a b = forall p (f :: * -> *) . 471#endif 472 p a (f b) -> p s (f t) 473 474-- | A 'Simple' 'Equality'. 475type Equality' s a = Equality s s a a 476 477-- | Composable `asTypeOf`. Useful for constraining excess 478-- polymorphism, @foo . (id :: As Int) . bar@. 479type As a = Equality' a a 480 481------------------------------------------------------------------------------- 482-- Getters 483------------------------------------------------------------------------------- 484 485-- | A 'Getter' describes how to retrieve a single value in a way that can be 486-- composed with other 'LensLike' constructions. 487-- 488-- Unlike a 'Lens' a 'Getter' is read-only. Since a 'Getter' 489-- cannot be used to write back there are no 'Lens' laws that can be applied to 490-- it. In fact, it is isomorphic to an arbitrary function from @(s -> a)@. 491-- 492-- Moreover, a 'Getter' can be used directly as a 'Control.Lens.Fold.Fold', 493-- since it just ignores the 'Applicative'. 494type Getter s a = forall f. (Contravariant f, Functor f) => (a -> f a) -> s -> f s 495 496-- | Every 'IndexedGetter' is a valid 'Control.Lens.Fold.IndexedFold' and can be used for 'Control.Lens.Getter.Getting' like a 'Getter'. 497type IndexedGetter i s a = forall p f. (Indexable i p, Contravariant f, Functor f) => p a (f a) -> s -> f s 498 499-- | An 'IndexPreservingGetter' can be used as a 'Getter', but when composed with an 'IndexedTraversal', 500-- 'IndexedFold', or 'IndexedLens' yields an 'IndexedFold', 'IndexedFold' or 'IndexedGetter' respectively. 501type IndexPreservingGetter s a = forall p f. (Conjoined p, Contravariant f, Functor f) => p a (f a) -> p s (f s) 502 503-------------------------- 504-- Folds 505-------------------------- 506 507-- | A 'Fold' describes how to retrieve multiple values in a way that can be composed 508-- with other 'LensLike' constructions. 509-- 510-- A @'Fold' s a@ provides a structure with operations very similar to those of the 'Data.Foldable.Foldable' 511-- typeclass, see 'Control.Lens.Fold.foldMapOf' and the other 'Fold' combinators. 512-- 513-- By convention, if there exists a 'foo' method that expects a @'Data.Foldable.Foldable' (f a)@, then there should be a 514-- @fooOf@ method that takes a @'Fold' s a@ and a value of type @s@. 515-- 516-- A 'Getter' is a legal 'Fold' that just ignores the supplied 'Data.Monoid.Monoid'. 517-- 518-- Unlike a 'Control.Lens.Traversal.Traversal' a 'Fold' is read-only. Since a 'Fold' cannot be used to write back 519-- there are no 'Lens' laws that apply. 520type Fold s a = forall f. (Contravariant f, Applicative f) => (a -> f a) -> s -> f s 521 522-- | Every 'IndexedFold' is a valid 'Control.Lens.Fold.Fold' and can be used for 'Control.Lens.Getter.Getting'. 523type IndexedFold i s a = forall p f. (Indexable i p, Contravariant f, Applicative f) => p a (f a) -> s -> f s 524 525-- | An 'IndexPreservingFold' can be used as a 'Fold', but when composed with an 'IndexedTraversal', 526-- 'IndexedFold', or 'IndexedLens' yields an 'IndexedFold' respectively. 527type IndexPreservingFold s a = forall p f. (Conjoined p, Contravariant f, Applicative f) => p a (f a) -> p s (f s) 528 529-- | A relevant Fold (aka 'Fold1') has one or more targets. 530type Fold1 s a = forall f. (Contravariant f, Apply f) => (a -> f a) -> s -> f s 531type IndexedFold1 i s a = forall p f. (Indexable i p, Contravariant f, Apply f) => p a (f a) -> s -> f s 532type IndexPreservingFold1 s a = forall p f. (Conjoined p, Contravariant f, Apply f) => p a (f a) -> p s (f s) 533 534------------------------------------------------------------------------------- 535-- Simple Overloading 536------------------------------------------------------------------------------- 537 538-- | A 'Simple' 'Lens', 'Simple' 'Traversal', ... can 539-- be used instead of a 'Lens','Traversal', ... 540-- whenever the type variables don't change upon setting a value. 541-- 542-- @ 543-- 'Data.Complex.Lens._imagPart' :: 'Simple' 'Lens' ('Data.Complex.Complex' a) a 544-- 'Control.Lens.Traversal.traversed' :: 'Simple' ('IndexedTraversal' 'Int') [a] a 545-- @ 546-- 547-- Note: To use this alias in your own code with @'LensLike' f@ or 548-- 'Setter', you may have to turn on @LiberalTypeSynonyms@. 549-- 550-- This is commonly abbreviated as a \"prime\" marker, /e.g./ 'Lens'' = 'Simple' 'Lens'. 551type Simple f s a = f s s a a 552 553------------------------------------------------------------------------------- 554-- Optics 555------------------------------------------------------------------------------- 556 557-- | A valid 'Optic' @l@ should satisfy the laws: 558-- 559-- @ 560-- l 'pure' ≡ 'pure' 561-- l ('Procompose' f g) = 'Procompose' (l f) (l g) 562-- @ 563-- 564-- This gives rise to the laws for 'Equality', 'Iso', 'Prism', 'Lens', 565-- 'Traversal', 'Traversal1', 'Setter', 'Fold', 'Fold1', and 'Getter' as well 566-- along with their index-preserving variants. 567-- 568-- @ 569-- type 'LensLike' f s t a b = 'Optic' (->) f s t a b 570-- @ 571type Optic p f s t a b = p a (f b) -> p s (f t) 572 573-- | @ 574-- type 'Optic'' p f s a = 'Simple' ('Optic' p f) s a 575-- @ 576type Optic' p f s a = Optic p f s s a a 577 578-- | @ 579-- type 'LensLike' f s t a b = 'Optical' (->) (->) f s t a b 580-- @ 581-- 582-- @ 583-- type 'Over' p f s t a b = 'Optical' p (->) f s t a b 584-- @ 585-- 586-- @ 587-- type 'Optic' p f s t a b = 'Optical' p p f s t a b 588-- @ 589type Optical p q f s t a b = p a (f b) -> q s (f t) 590 591-- | @ 592-- type 'Optical'' p q f s a = 'Simple' ('Optical' p q f) s a 593-- @ 594type Optical' p q f s a = Optical p q f s s a a 595 596 597-- | Many combinators that accept a 'Lens' can also accept a 598-- 'Traversal' in limited situations. 599-- 600-- They do so by specializing the type of 'Functor' that they require of the 601-- caller. 602-- 603-- If a function accepts a @'LensLike' f s t a b@ for some 'Functor' @f@, 604-- then they may be passed a 'Lens'. 605-- 606-- Further, if @f@ is an 'Applicative', they may also be passed a 607-- 'Traversal'. 608type LensLike f s t a b = (a -> f b) -> s -> f t 609 610-- | @ 611-- type 'LensLike'' f = 'Simple' ('LensLike' f) 612-- @ 613type LensLike' f s a = LensLike f s s a a 614 615-- | Convenient alias for constructing indexed lenses and their ilk. 616type IndexedLensLike i f s t a b = forall p. Indexable i p => p a (f b) -> s -> f t 617 618-- | Convenient alias for constructing simple indexed lenses and their ilk. 619type IndexedLensLike' i f s a = IndexedLensLike i f s s a a 620 621-- | This is a convenient alias for use when you need to consume either indexed or non-indexed lens-likes based on context. 622type Over p f s t a b = p a (f b) -> s -> f t 623 624-- | This is a convenient alias for use when you need to consume either indexed or non-indexed lens-likes based on context. 625-- 626-- @ 627-- type 'Over'' p f = 'Simple' ('Over' p f) 628-- @ 629type Over' p f s a = Over p f s s a a 630