···1616to study the history of lenses, then build up to the most recent theories, it is
1717best to start at the `Lets.GetSetLens` module. If you wish to derive the
1818structure of lenses from first principles, then derive the more modern theories,
1919-start at the `Lets.Lens.Lens` module.
1919+start at the `Lets.Lens` module.
20202121Exercises can be recognised by filling in a function body that has a placeholder
2222of `error "todo: <function-name>"`.
···4949described by Twan van Laarhoven. This representation also introduces a
5050generalisation of lenses to permit *polymorphic update* of structures.
51515252-##### `Lets.Lens.Lens`
5252+##### `Lets.Lens`
53535454This series of exercises starts at first principles to derive the concept of a
5555lens, as it was first described by Twan van Laarhoven. The derivation then goes
···11+{-# LANGUAGE RankNTypes #-}
22+13module Lets.Lens (
22- module L
44+ fmapT
55+, over
66+, fmapTAgain
77+, Set
88+, sets
99+, mapped
1010+, set
1111+, foldMapT
1212+, foldMapOf
1313+, foldMapTAgain
1414+, Fold
1515+, folds
1616+, folded
1717+, Get
1818+, get
1919+, Traversal
2020+, both
2121+, traverseLeft
2222+, traverseRight
2323+, Traversal'
2424+, Lens
2525+, Prism
2626+, _Left
2727+, _Right
2828+, prism
2929+, _Just
3030+, _Nothing
3131+, setP
3232+, getP
3333+, Prism'
3434+, modify
3535+, (%~)
3636+, (.~)
3737+, fmodify
3838+, (|=)
3939+, fstL
4040+, sndL
4141+, mapL
4242+, setL
4343+, compose
4444+, (|.)
4545+, identity
4646+, product
4747+, (***)
4848+, choice
4949+, (|||)
5050+, Lens'
5151+, cityL
5252+, stateL
5353+, countryL
5454+, streetL
5555+, suburbL
5656+, localityL
5757+, ageL
5858+, nameL
5959+, addressL
6060+, intAndIntL
6161+, intAndL
6262+, getSuburb
6363+, setStreet
6464+, getAgeAndCountry
6565+, setCityAndLocality
6666+, getSuburbOrCity
6767+, setStreetOrState
6868+, modifyCityUppercase
6969+, modifyIntAndLengthEven
7070+, traverseLocality
7171+, intOrIntP
7272+, intOrP
7373+, intOrLengthEven
374) where
47555-import Lets.Lens.Choice as L
66-import Lets.Lens.Lens as L
77-import Lets.Lens.Profunctor as L
7676+import Control.Applicative(Applicative((<*>), pure))
7777+import Data.Bool(bool)
7878+import Data.Char(toUpper)
7979+import Data.Foldable(Foldable(foldMap))
8080+import Data.Functor((<$>))
8181+import Data.Map(Map)
8282+import qualified Data.Map as Map(insert, delete, lookup)
8383+import Data.Monoid(Monoid)
8484+import qualified Data.Set as Set(Set, insert, delete, member)
8585+import Data.Traversable(Traversable(traverse))
8686+import Lets.Data(AlongsideLeft(AlongsideLeft, getAlongsideLeft), AlongsideRight(AlongsideRight, getAlongsideRight), Identity(Identity, getIdentity), Const(Const, getConst), Tagged(Tagged, getTagged), IntOr(IntOrIs, IntOrIsNot), IntAnd(IntAnd), Person(Person), Locality(Locality), Address(Address))
8787+import Lets.Choice(Choice(left, right))
8888+import Lets.Profunctor(Profunctor(dimap))
8989+import Prelude hiding (product)
9090+9191+-- $setup
9292+-- >>> import qualified Data.Map as Map(fromList)
9393+-- >>> import qualified Data.Set as Set(fromList)
9494+-- >>> import Data.Char(ord)
9595+9696+-- Let's remind ourselves of Traversable, noting Foldable and Functor.
9797+--
9898+-- class (Foldable t, Functor t) => Traversable t where
9999+-- traverse ::
100100+-- Applicative f =>
101101+-- (a -> f b)
102102+-- -> t a
103103+-- -> f (t b)
104104+105105+-- | Observe that @fmap@ can be recovered from @traverse@ using @Identity@.
106106+--
107107+-- /Reminder:/ fmap :: Functor t => (a -> b) -> t a -> t b
108108+fmapT ::
109109+ Traversable t =>
110110+ (a -> b)
111111+ -> t a
112112+ -> t b
113113+fmapT =
114114+ error "todo: fmapT"
115115+116116+-- | Let's refactor out the call to @traverse@ as an argument to @fmapT@.
117117+over ::
118118+ ((a -> Identity b) -> s -> Identity t)
119119+ -> (a -> b)
120120+ -> s
121121+ -> t
122122+over =
123123+ error "todo: over"
124124+125125+-- | Here is @fmapT@ again, passing @traverse@ to @over@.
126126+fmapTAgain ::
127127+ Traversable t =>
128128+ (a -> b)
129129+ -> t a
130130+ -> t b
131131+fmapTAgain =
132132+ error "todo: fmapTAgain"
133133+134134+-- | Let's create a type-alias for this type of function.
135135+type Set s t a b =
136136+ (a -> Identity b)
137137+ -> s
138138+ -> Identity t
139139+140140+-- | Let's write an inverse to @over@ that does the @Identity@ wrapping &
141141+-- unwrapping.
142142+sets ::
143143+ ((a -> b) -> s -> t)
144144+ -> Set s t a b
145145+sets =
146146+ error "todo: sets"
147147+148148+mapped ::
149149+ Functor f =>
150150+ Set (f a) (f b) a b
151151+mapped =
152152+ error "todo: mapped"
153153+154154+set ::
155155+ Set s t a b
156156+ -> s
157157+ -> b
158158+ -> t
159159+set =
160160+ error "todo: set"
161161+162162+----
163163+164164+-- | Observe that @fmap@ can be recovered from @traverse@ using @Identity@.
165165+--
166166+-- /Reminder:/ foldMap :: (Foldable t, Monoid b) => (a -> b) -> t a -> b
167167+foldMapT ::
168168+ (Traversable t, Monoid b) =>
169169+ (a -> b)
170170+ -> t a
171171+ -> b
172172+foldMapT =
173173+ error "todo: foldMapT"
174174+175175+-- | Let's refactor out the call to @traverse@ as an argument to @foldMapT@.
176176+foldMapOf ::
177177+ ((a -> Const r b) -> s -> Const r t)
178178+ -> (a -> r)
179179+ -> s
180180+ -> r
181181+foldMapOf =
182182+ error "todo: foldMapOf"
183183+184184+-- | Here is @foldMapT@ again, passing @traverse@ to @foldMapOf@.
185185+foldMapTAgain ::
186186+ (Traversable t, Monoid b) =>
187187+ (a -> b)
188188+ -> t a
189189+ -> b
190190+foldMapTAgain =
191191+ error "todo: foldMapTAgain"
192192+193193+-- | Let's create a type-alias for this type of function.
194194+type Fold s t a b =
195195+ forall r.
196196+ Monoid r =>
197197+ (a -> Const r b)
198198+ -> s
199199+ -> Const r t
200200+201201+-- | Let's write an inverse to @foldMapOf@ that does the @Const@ wrapping &
202202+-- unwrapping.
203203+folds ::
204204+ ((a -> b) -> s -> t)
205205+ -> (a -> Const b a)
206206+ -> s
207207+ -> Const t s
208208+folds =
209209+ error "todo: folds"
210210+211211+folded ::
212212+ Foldable f =>
213213+ Fold (f a) (f a) a a
214214+folded =
215215+ error "todo: folded"
216216+217217+----
218218+219219+-- | @Get@ is like @Fold@, but without the @Monoid@ constraint.
220220+type Get r s a =
221221+ (a -> Const r a)
222222+ -> s
223223+ -> Const r s
224224+225225+get ::
226226+ Get a s a
227227+ -> s
228228+ -> a
229229+get =
230230+ error "todo: get"
231231+232232+----
233233+234234+-- | Let's generalise @Identity@ and @Const r@ to any @Applicative@ instance.
235235+type Traversal s t a b =
236236+ forall f.
237237+ Applicative f =>
238238+ (a -> f b)
239239+ -> s
240240+ -> f t
241241+242242+-- | Traverse both sides of a pair.
243243+both ::
244244+ Traversal (a, a) (b, b) a b
245245+both =
246246+ error "todo: both"
247247+248248+-- | Traverse the left side of @Either@.
249249+traverseLeft ::
250250+ Traversal (Either a x) (Either b x) a b
251251+traverseLeft =
252252+ error "todo: traverseLeft"
253253+254254+-- | Traverse the right side of @Either@.
255255+traverseRight ::
256256+ Traversal (Either x a) (Either x b) a b
257257+traverseRight =
258258+ error "todo: traverseRight"
259259+260260+type Traversal' a b =
261261+ Traversal a a b b
262262+263263+----
264264+265265+-- | @Const r@ is @Applicative@, if @Monoid r@, however, without the @Monoid@
266266+-- constraint (as in @Get@), the only shared abstraction between @Identity@ and
267267+-- @Const r@ is @Functor@.
268268+--
269269+-- Consequently, we arrive at our lens derivation:
270270+type Lens s t a b =
271271+ forall f.
272272+ Functor f =>
273273+ (a -> f b)
274274+ -> s
275275+ -> f t
276276+277277+----
278278+279279+-- | A prism is a less specific type of traversal.
280280+type Prism s t a b =
281281+ forall p f.
282282+ (Choice p, Applicative f) =>
283283+ p a (f b)
284284+ -> p s (f t)
285285+286286+_Left ::
287287+ Prism (Either a x) (Either b x) a b
288288+_Left =
289289+ error "todo: _Left"
290290+291291+_Right ::
292292+ Prism (Either x a) (Either x b) a b
293293+_Right =
294294+ error "todo: _Right"
295295+296296+prism ::
297297+ (b -> t)
298298+ -> (s -> Either t a)
299299+ -> Prism s t a b
300300+prism =
301301+ error "todo: prism"
302302+303303+_Just ::
304304+ Prism (Maybe a) (Maybe b) a b
305305+_Just =
306306+ error "todo: _Just"
307307+308308+_Nothing ::
309309+ Prism (Maybe a) (Maybe a) () ()
310310+_Nothing =
311311+ error "todo: _Nothing"
312312+313313+setP ::
314314+ Prism s t a b
315315+ -> s
316316+ -> Either t a
317317+setP =
318318+ error "todo: setP"
319319+320320+getP ::
321321+ Prism s t a b
322322+ -> b
323323+ -> t
324324+getP =
325325+ error "todo: getP"
326326+327327+type Prism' a b =
328328+ Prism a a b b
329329+330330+----
331331+332332+-- |
333333+--
334334+-- >>> modify fstL (+1) (0 :: Int, "abc")
335335+-- (1,"abc")
336336+--
337337+-- >>> modify sndL (+1) ("abc", 0 :: Int)
338338+-- ("abc",1)
339339+--
340340+-- prop> let types = (x :: Int, y :: String) in modify fstL id (x, y) == (x, y)
341341+--
342342+-- prop> let types = (x :: Int, y :: String) in modify sndL id (x, y) == (x, y)
343343+modify ::
344344+ Lens s t a b
345345+ -> (a -> b)
346346+ -> s
347347+ -> t
348348+modify =
349349+ error "todo: modify"
350350+351351+-- | An alias for @modify@.
352352+(%~) ::
353353+ Lens s t a b
354354+ -> (a -> b)
355355+ -> s
356356+ -> t
357357+(%~) =
358358+ modify
359359+360360+infixr 4 %~
361361+362362+-- |
363363+--
364364+-- >>> fstL .~ 1 $ (0 :: Int, "abc")
365365+-- (1,"abc")
366366+--
367367+-- >>> sndL .~ 1 $ ("abc", 0 :: Int)
368368+-- ("abc",1)
369369+--
370370+-- prop> let types = (x :: Int, y :: String) in set fstL (x, y) z == (fstL .~ z $ (x, y))
371371+--
372372+-- prop> let types = (x :: Int, y :: String) in set sndL (x, y) z == (sndL .~ z $ (x, y))
373373+(.~) ::
374374+ Lens s t a b
375375+ -> b
376376+ -> s
377377+ -> t
378378+(.~) =
379379+ error "todo: (.~)"
380380+381381+infixl 5 .~
382382+383383+-- |
384384+--
385385+-- >>> fmodify fstL (+) (5 :: Int, "abc") 8
386386+-- (13,"abc")
387387+--
388388+-- >>> fmodify fstL (\n -> bool Nothing (Just (n * 2)) (even n)) (10, "abc")
389389+-- Just (20,"abc")
390390+--
391391+-- >>> fmodify fstL (\n -> bool Nothing (Just (n * 2)) (even n)) (11, "abc")
392392+-- Nothing
393393+fmodify ::
394394+ Functor f =>
395395+ Lens s t a b
396396+ -> (a -> f b)
397397+ -> s
398398+ -> f t
399399+fmodify =
400400+ error "todo: fmodify"
401401+402402+-- |
403403+--
404404+-- >>> fstL |= Just 3 $ (7, "abc")
405405+-- Just (3,"abc")
406406+--
407407+-- >>> (fstL |= (+1) $ (3, "abc")) 17
408408+-- (18,"abc")
409409+(|=) ::
410410+ Functor f =>
411411+ Lens s t a b
412412+ -> f b
413413+ -> s
414414+ -> f t
415415+(|=) =
416416+ error "todo: (|=)"
417417+418418+infixl 5 |=
419419+420420+-- |
421421+--
422422+-- >>> modify fstL (*10) (3, "abc")
423423+-- (30,"abc")
424424+fstL ::
425425+ Lens (a, x) (b, x) a b
426426+fstL =
427427+ error "todo: fstL"
428428+429429+-- |
430430+--
431431+-- >>> modify sndL (++ "def") (13, "abc")
432432+-- (13,"abcdef")
433433+sndL ::
434434+ Lens (x, a) (x, b) a b
435435+sndL =
436436+ error "todo: sndL"
437437+438438+-- |
439439+--
440440+-- >>> get (mapL 3) (Map.fromList (map (\c -> (ord c - 96, c)) ['a'..'d']))
441441+-- Just 'c'
442442+--
443443+-- >>> get (mapL 33) (Map.fromList (map (\c -> (ord c - 96, c)) ['a'..'d']))
444444+-- Nothing
445445+--
446446+-- >>> set (mapL 3) (Map.fromList (map (\c -> (ord c - 96, c)) ['a'..'d'])) (Just 'X')
447447+-- fromList [(1,'a'),(2,'b'),(3,'X'),(4,'d')]
448448+--
449449+-- >>> set (mapL 33) (Map.fromList (map (\c -> (ord c - 96, c)) ['a'..'d'])) (Just 'X')
450450+-- fromList [(1,'a'),(2,'b'),(3,'c'),(4,'d'),(33,'X')]
451451+--
452452+-- >>> set (mapL 3) (Map.fromList (map (\c -> (ord c - 96, c)) ['a'..'d'])) Nothing
453453+-- fromList [(1,'a'),(2,'b'),(4,'d')]
454454+--
455455+-- >>> set (mapL 33) (Map.fromList (map (\c -> (ord c - 96, c)) ['a'..'d'])) Nothing
456456+-- fromList [(1,'a'),(2,'b'),(3,'c'),(4,'d')]
457457+mapL ::
458458+ Ord k =>
459459+ k
460460+ -> Lens (Map k v) (Map k v) (Maybe v) (Maybe v)
461461+mapL =
462462+ error "todo: mapL"
463463+464464+-- |
465465+--
466466+-- >>> get (setL 3) (Set.fromList [1..5])
467467+-- True
468468+--
469469+-- >>> get (setL 33) (Set.fromList [1..5])
470470+-- False
471471+--
472472+-- >>> set (setL 3) (Set.fromList [1..5]) True
473473+-- fromList [1,2,3,4,5]
474474+--
475475+-- >>> set (setL 3) (Set.fromList [1..5]) False
476476+-- fromList [1,2,4,5]
477477+--
478478+-- >>> set (setL 33) (Set.fromList [1..5]) True
479479+-- fromList [1,2,3,4,5,33]
480480+--
481481+-- >>> set (setL 33) (Set.fromList [1..5]) False
482482+-- fromList [1,2,3,4,5]
483483+setL ::
484484+ Ord k =>
485485+ k
486486+ -> Lens (Set.Set k) (Set.Set k) Bool Bool
487487+setL =
488488+ error "todo: setL"
489489+490490+-- |
491491+--
492492+-- >>> get (compose fstL sndL) ("abc", (7, "def"))
493493+-- 7
494494+--
495495+-- >>> set (compose fstL sndL) ("abc", (7, "def")) 8
496496+-- ("abc",(8,"def"))
497497+compose ::
498498+ Lens s t a b
499499+ -> Lens q r s t
500500+ -> Lens q r a b
501501+compose =
502502+ error "todo: compose"
503503+504504+-- | An alias for @compose@.
505505+(|.) ::
506506+ Lens s t a b
507507+ -> Lens q r s t
508508+ -> Lens q r a b
509509+(|.) =
510510+ compose
511511+512512+infixr 9 |.
513513+514514+-- |
515515+--
516516+-- >>> get identity 3
517517+-- 3
518518+--
519519+-- >>> set identity 3 4
520520+-- 4
521521+identity ::
522522+ Lens a b a b
523523+identity =
524524+ error "todo: identity"
525525+526526+-- |
527527+--
528528+-- >>> get (product fstL sndL) (("abc", 3), (4, "def"))
529529+-- ("abc","def")
530530+--
531531+-- >>> set (product fstL sndL) (("abc", 3), (4, "def")) ("ghi", "jkl")
532532+-- (("ghi",3),(4,"jkl"))
533533+product ::
534534+ Lens s t a b
535535+ -> Lens q r c d
536536+ -> Lens (s, q) (t, r) (a, c) (b, d)
537537+product =
538538+ error "todo: product"
539539+540540+-- | An alias for @product@.
541541+(***) ::
542542+ Lens s t a b
543543+ -> Lens q r c d
544544+ -> Lens (s, q) (t, r) (a, c) (b, d)
545545+(***) =
546546+ product
547547+548548+infixr 3 ***
549549+550550+-- |
551551+--
552552+-- >>> get (choice fstL sndL) (Left ("abc", 7))
553553+-- "abc"
554554+--
555555+-- >>> get (choice fstL sndL) (Right ("abc", 7))
556556+-- 7
557557+--
558558+-- >>> set (choice fstL sndL) (Left ("abc", 7)) "def"
559559+-- Left ("def",7)
560560+--
561561+-- >>> set (choice fstL sndL) (Right ("abc", 7)) 8
562562+-- Right ("abc",8)
563563+choice ::
564564+ Lens s t a b
565565+ -> Lens q r a b
566566+ -> Lens (Either s q) (Either t r) a b
567567+choice =
568568+ error "todo: choice"
569569+570570+-- | An alias for @choice@.
571571+(|||) ::
572572+ Lens s t a b
573573+ -> Lens q r a b
574574+ -> Lens (Either s q) (Either t r) a b
575575+(|||) =
576576+ choice
577577+578578+infixr 2 |||
579579+580580+----
581581+582582+type Lens' a b =
583583+ Lens a a b b
584584+585585+cityL ::
586586+ Lens' Locality String
587587+cityL p (Locality c t y) =
588588+ fmap (\c' -> Locality c' t y) (p c)
589589+590590+stateL ::
591591+ Lens' Locality String
592592+stateL p (Locality c t y) =
593593+ fmap (\t' -> Locality c t' y) (p t)
594594+595595+countryL ::
596596+ Lens' Locality String
597597+countryL p (Locality c t y) =
598598+ fmap (\y' -> Locality c t y') (p y)
599599+600600+streetL ::
601601+ Lens' Address String
602602+streetL p (Address t s l) =
603603+ fmap (\t' -> Address t' s l) (p t)
604604+605605+suburbL ::
606606+ Lens' Address String
607607+suburbL p (Address t s l) =
608608+ fmap (\s' -> Address t s' l) (p s)
609609+610610+localityL ::
611611+ Lens' Address Locality
612612+localityL p (Address t s l) =
613613+ fmap (\l' -> Address t s l') (p l)
614614+615615+ageL ::
616616+ Lens' Person Int
617617+ageL p (Person a n d) =
618618+ fmap (\a' -> Person a' n d) (p a)
619619+620620+nameL ::
621621+ Lens' Person String
622622+nameL p (Person a n d) =
623623+ fmap (\n' -> Person a n' d) (p n)
624624+625625+addressL ::
626626+ Lens' Person Address
627627+addressL p (Person a n d) =
628628+ fmap (\d' -> Person a n d') (p d)
629629+630630+intAndIntL ::
631631+ Lens' (IntAnd a) Int
632632+intAndIntL p (IntAnd n a) =
633633+ fmap (\n' -> IntAnd n' a) (p n)
634634+635635+-- lens for polymorphic update
636636+intAndL ::
637637+ Lens (IntAnd a) (IntAnd b) a b
638638+intAndL p (IntAnd n a) =
639639+ fmap (\a' -> IntAnd n a') (p a)
640640+641641+-- |
642642+--
643643+-- >>> get (suburbL |. addressL) fred
644644+-- "Fredville"
645645+--
646646+-- >>> get (suburbL |. addressL) mary
647647+-- "Maryland"
648648+getSuburb ::
649649+ Person
650650+ -> String
651651+getSuburb =
652652+ error "todo: getSuburb"
653653+654654+-- |
655655+--
656656+-- >>> setStreet fred "Some Other St"
657657+-- Person 24 "Fred" (Address "Some Other St" "Fredville" (Locality "Fredmania" "New South Fred" "Fredalia"))
658658+--
659659+-- >>> setStreet mary "Some Other St"
660660+-- Person 28 "Mary" (Address "Some Other St" "Maryland" (Locality "Mary Mary" "Western Mary" "Maristan"))
661661+setStreet ::
662662+ Person
663663+ -> String
664664+ -> Person
665665+setStreet =
666666+ error "todo: setStreet"
667667+668668+-- |
669669+--
670670+-- >>> getAgeAndCountry (fred, maryLocality)
671671+-- (24,"Maristan")
672672+--
673673+-- >>> getAgeAndCountry (mary, fredLocality)
674674+-- (28,"Fredalia")
675675+getAgeAndCountry ::
676676+ (Person, Locality)
677677+ -> (Int, String)
678678+getAgeAndCountry =
679679+ error "todo: getAgeAndCountry"
680680+681681+-- |
682682+--
683683+-- >>> setCityAndLocality (fred, maryAddress) ("Some Other City", fredLocality)
684684+-- (Person 24 "Fred" (Address "15 Fred St" "Fredville" (Locality "Some Other City" "New South Fred" "Fredalia")),Address "83 Mary Ln" "Maryland" (Locality "Fredmania" "New South Fred" "Fredalia"))
685685+--
686686+-- >>> setCityAndLocality (mary, fredAddress) ("Some Other City", maryLocality)
687687+-- (Person 28 "Mary" (Address "83 Mary Ln" "Maryland" (Locality "Some Other City" "Western Mary" "Maristan")),Address "15 Fred St" "Fredville" (Locality "Mary Mary" "Western Mary" "Maristan"))
688688+setCityAndLocality ::
689689+ (Person, Address) -> (String, Locality) -> (Person, Address)
690690+setCityAndLocality =
691691+ error "todo: setCityAndLocality"
692692+693693+-- |
694694+--
695695+-- >>> getSuburbOrCity (Left maryAddress)
696696+-- "Maryland"
697697+--
698698+-- >>> getSuburbOrCity (Right fredLocality)
699699+-- "Fredmania"
700700+getSuburbOrCity ::
701701+ Either Address Locality
702702+ -> String
703703+getSuburbOrCity =
704704+ error "todo: getSuburbOrCity"
705705+706706+-- |
707707+--
708708+-- >>> setStreetOrState (Right maryLocality) "Some Other State"
709709+-- Right (Locality "Mary Mary" "Some Other State" "Maristan")
710710+--
711711+-- >>> setStreetOrState (Left fred) "Some Other St"
712712+-- Left (Person 24 "Fred" (Address "Some Other St" "Fredville" (Locality "Fredmania" "New South Fred" "Fredalia")))
713713+setStreetOrState ::
714714+ Either Person Locality
715715+ -> String
716716+ -> Either Person Locality
717717+setStreetOrState =
718718+ error "todo: setStreetOrState"
719719+720720+-- |
721721+--
722722+-- >>> modifyCityUppercase fred
723723+-- Person 24 "Fred" (Address "15 Fred St" "Fredville" (Locality "FREDMANIA" "New South Fred" "Fredalia"))
724724+--
725725+-- >>> modifyCityUppercase mary
726726+-- Person 28 "Mary" (Address "83 Mary Ln" "Maryland" (Locality "MARY MARY" "Western Mary" "Maristan"))
727727+modifyCityUppercase ::
728728+ Person
729729+ -> Person
730730+modifyCityUppercase =
731731+ error "todo: modifyCityUppercase"
732732+733733+-- |
734734+--
735735+-- >>> modifyIntAndLengthEven (IntAnd 10 "abc")
736736+-- IntAnd 10 False
737737+--
738738+-- >>> modifyIntAndLengthEven (IntAnd 10 "abcd")
739739+-- IntAnd 10 True
740740+modifyIntAndLengthEven ::
741741+ IntAnd [a]
742742+ -> IntAnd Bool
743743+modifyIntAndLengthEven =
744744+ error "todo: modifyIntAndLengthEven"
745745+746746+----
747747+748748+-- |
749749+--
750750+-- >>> over traverseLocality (map toUpper) (Locality "abc" "def" "ghi")
751751+-- Locality "ABC" "DEF" "GHI"
752752+traverseLocality ::
753753+ Traversal' Locality String
754754+traverseLocality =
755755+ error "todo: traverseLocality"
756756+757757+-- |
758758+--
759759+-- >>> over intOrIntP (*10) (IntOrIs 3)
760760+-- IntOrIs 30
761761+--
762762+-- >>> over intOrIntP (*10) (IntOrIsNot "abc")
763763+-- IntOrIsNot "abc"
764764+intOrIntP ::
765765+ Prism' (IntOr a) Int
766766+intOrIntP =
767767+ error "todo: intOrIntP"
768768+769769+intOrP ::
770770+ Prism (IntOr a) (IntOr b) a b
771771+intOrP =
772772+ error "todo: intOrP"
773773+774774+-- |
775775+--
776776+-- >> over intOrP (even . length) (IntOrIsNot "abc")
777777+-- IntOrIsNot False
778778+--
779779+-- >>> over intOrP (even . length) (IntOrIsNot "abcd")
780780+-- IntOrIsNot True
781781+--
782782+-- >>> over intOrP (even . length) (IntOrIs 10)
783783+-- IntOrIs 10
784784+intOrLengthEven ::
785785+ IntOr [a]
786786+ -> IntOr Bool
787787+intOrLengthEven =
788788+ error "todo: intOrLengthEven"
···11-{-# LANGUAGE RankNTypes #-}
22-33-module Lets.Lens.Lens (
44- fmapT
55-, over
66-, fmapTAgain
77-, Set
88-, sets
99-, mapped
1010-, set
1111-, foldMapT
1212-, foldMapOf
1313-, foldMapTAgain
1414-, Fold
1515-, folds
1616-, folded
1717-, Get
1818-, get
1919-, Traversal
2020-, both
2121-, traverseLeft
2222-, traverseRight
2323-, Traversal'
2424-, Lens
2525-, Prism
2626-, _Left
2727-, _Right
2828-, prism
2929-, _Just
3030-, _Nothing
3131-, setP
3232-, getP
3333-, Prism'
3434-, modify
3535-, (%~)
3636-, (.~)
3737-, fmodify
3838-, (|=)
3939-, fstL
4040-, sndL
4141-, mapL
4242-, setL
4343-, compose
4444-, (|.)
4545-, identity
4646-, product
4747-, (***)
4848-, choice
4949-, (|||)
5050-, Lens'
5151-, cityL
5252-, stateL
5353-, countryL
5454-, streetL
5555-, suburbL
5656-, localityL
5757-, ageL
5858-, nameL
5959-, addressL
6060-, intAndIntL
6161-, intAndL
6262-, getSuburb
6363-, setStreet
6464-, getAgeAndCountry
6565-, setCityAndLocality
6666-, getSuburbOrCity
6767-, setStreetOrState
6868-, modifyCityUppercase
6969-, modifyIntAndLengthEven
7070-, traverseLocality
7171-, intOrIntP
7272-, intOrP
7373-, intOrLengthEven
7474-) where
7575-7676-import Control.Applicative(Applicative((<*>), pure))
7777-import Data.Bool(bool)
7878-import Data.Char(toUpper)
7979-import Data.Foldable(Foldable(foldMap))
8080-import Data.Functor((<$>))
8181-import Data.Map(Map)
8282-import qualified Data.Map as Map(insert, delete, lookup)
8383-import Data.Monoid(Monoid)
8484-import qualified Data.Set as Set(Set, insert, delete, member)
8585-import Data.Traversable(Traversable(traverse))
8686-import Lets.Data(AlongsideLeft(AlongsideLeft, getAlongsideLeft), AlongsideRight(AlongsideRight, getAlongsideRight), Identity(Identity, getIdentity), Const(Const, getConst), Tagged(Tagged, getTagged), IntOr(IntOrIs, IntOrIsNot), IntAnd(IntAnd), Person(Person), Locality(Locality), Address(Address))
8787-import Lets.Lens.Choice(Choice(left, right))
8888-import Lets.Lens.Profunctor(Profunctor(dimap))
8989-import Prelude hiding (product)
9090-9191--- $setup
9292--- >>> import qualified Data.Map as Map(fromList)
9393--- >>> import qualified Data.Set as Set(fromList)
9494--- >>> import Data.Char(ord)
9595-9696--- Let's remind ourselves of Traversable, noting Foldable and Functor.
9797---
9898--- class (Foldable t, Functor t) => Traversable t where
9999--- traverse ::
100100--- Applicative f =>
101101--- (a -> f b)
102102--- -> t a
103103--- -> f (t b)
104104-105105--- | Observe that @fmap@ can be recovered from @traverse@ using @Identity@.
106106---
107107--- /Reminder:/ fmap :: Functor t => (a -> b) -> t a -> t b
108108-fmapT ::
109109- Traversable t =>
110110- (a -> b)
111111- -> t a
112112- -> t b
113113-fmapT =
114114- error "todo: fmapT"
115115-116116--- | Let's refactor out the call to @traverse@ as an argument to @fmapT@.
117117-over ::
118118- ((a -> Identity b) -> s -> Identity t)
119119- -> (a -> b)
120120- -> s
121121- -> t
122122-over =
123123- error "todo: over"
124124-125125--- | Here is @fmapT@ again, passing @traverse@ to @over@.
126126-fmapTAgain ::
127127- Traversable t =>
128128- (a -> b)
129129- -> t a
130130- -> t b
131131-fmapTAgain =
132132- error "todo: fmapTAgain"
133133-134134--- | Let's create a type-alias for this type of function.
135135-type Set s t a b =
136136- (a -> Identity b)
137137- -> s
138138- -> Identity t
139139-140140--- | Let's write an inverse to @over@ that does the @Identity@ wrapping &
141141--- unwrapping.
142142-sets ::
143143- ((a -> b) -> s -> t)
144144- -> Set s t a b
145145-sets =
146146- error "todo: sets"
147147-148148-mapped ::
149149- Functor f =>
150150- Set (f a) (f b) a b
151151-mapped =
152152- error "todo: mapped"
153153-154154-set ::
155155- Set s t a b
156156- -> s
157157- -> b
158158- -> t
159159-set =
160160- error "todo: set"
161161-162162-----
163163-164164--- | Observe that @fmap@ can be recovered from @traverse@ using @Identity@.
165165---
166166--- /Reminder:/ foldMap :: (Foldable t, Monoid b) => (a -> b) -> t a -> b
167167-foldMapT ::
168168- (Traversable t, Monoid b) =>
169169- (a -> b)
170170- -> t a
171171- -> b
172172-foldMapT =
173173- error "todo: foldMapT"
174174-175175--- | Let's refactor out the call to @traverse@ as an argument to @foldMapT@.
176176-foldMapOf ::
177177- ((a -> Const r b) -> s -> Const r t)
178178- -> (a -> r)
179179- -> s
180180- -> r
181181-foldMapOf =
182182- error "todo: foldMapOf"
183183-184184--- | Here is @foldMapT@ again, passing @traverse@ to @foldMapOf@.
185185-foldMapTAgain ::
186186- (Traversable t, Monoid b) =>
187187- (a -> b)
188188- -> t a
189189- -> b
190190-foldMapTAgain =
191191- error "todo: foldMapTAgain"
192192-193193--- | Let's create a type-alias for this type of function.
194194-type Fold s t a b =
195195- forall r.
196196- Monoid r =>
197197- (a -> Const r b)
198198- -> s
199199- -> Const r t
200200-201201--- | Let's write an inverse to @foldMapOf@ that does the @Const@ wrapping &
202202--- unwrapping.
203203-folds ::
204204- ((a -> b) -> s -> t)
205205- -> (a -> Const b a)
206206- -> s
207207- -> Const t s
208208-folds =
209209- error "todo: folds"
210210-211211-folded ::
212212- Foldable f =>
213213- Fold (f a) (f a) a a
214214-folded =
215215- error "todo: folded"
216216-217217-----
218218-219219--- | @Get@ is like @Fold@, but without the @Monoid@ constraint.
220220-type Get r s a =
221221- (a -> Const r a)
222222- -> s
223223- -> Const r s
224224-225225-get ::
226226- Get a s a
227227- -> s
228228- -> a
229229-get =
230230- error "todo: get"
231231-232232-----
233233-234234--- | Let's generalise @Identity@ and @Const r@ to any @Applicative@ instance.
235235-type Traversal s t a b =
236236- forall f.
237237- Applicative f =>
238238- (a -> f b)
239239- -> s
240240- -> f t
241241-242242--- | Traverse both sides of a pair.
243243-both ::
244244- Traversal (a, a) (b, b) a b
245245-both =
246246- error "todo: both"
247247-248248--- | Traverse the left side of @Either@.
249249-traverseLeft ::
250250- Traversal (Either a x) (Either b x) a b
251251-traverseLeft =
252252- error "todo: traverseLeft"
253253-254254--- | Traverse the right side of @Either@.
255255-traverseRight ::
256256- Traversal (Either x a) (Either x b) a b
257257-traverseRight =
258258- error "todo: traverseRight"
259259-260260-type Traversal' a b =
261261- Traversal a a b b
262262-263263-----
264264-265265--- | @Const r@ is @Applicative@, if @Monoid r@, however, without the @Monoid@
266266--- constraint (as in @Get@), the only shared abstraction between @Identity@ and
267267--- @Const r@ is @Functor@.
268268---
269269--- Consequently, we arrive at our lens derivation:
270270-type Lens s t a b =
271271- forall f.
272272- Functor f =>
273273- (a -> f b)
274274- -> s
275275- -> f t
276276-277277-----
278278-279279--- | A prism is a less specific type of traversal.
280280-type Prism s t a b =
281281- forall p f.
282282- (Choice p, Applicative f) =>
283283- p a (f b)
284284- -> p s (f t)
285285-286286-_Left ::
287287- Prism (Either a x) (Either b x) a b
288288-_Left =
289289- error "todo: _Left"
290290-291291-_Right ::
292292- Prism (Either x a) (Either x b) a b
293293-_Right =
294294- error "todo: _Right"
295295-296296-prism ::
297297- (b -> t)
298298- -> (s -> Either t a)
299299- -> Prism s t a b
300300-prism =
301301- error "todo: prism"
302302-303303-_Just ::
304304- Prism (Maybe a) (Maybe b) a b
305305-_Just =
306306- error "todo: _Just"
307307-308308-_Nothing ::
309309- Prism (Maybe a) (Maybe a) () ()
310310-_Nothing =
311311- error "todo: _Nothing"
312312-313313-setP ::
314314- Prism s t a b
315315- -> s
316316- -> Either t a
317317-setP =
318318- error "todo: setP"
319319-320320-getP ::
321321- Prism s t a b
322322- -> b
323323- -> t
324324-getP =
325325- error "todo: getP"
326326-327327-type Prism' a b =
328328- Prism a a b b
329329-330330-----
331331-332332--- |
333333---
334334--- >>> modify fstL (+1) (0 :: Int, "abc")
335335--- (1,"abc")
336336---
337337--- >>> modify sndL (+1) ("abc", 0 :: Int)
338338--- ("abc",1)
339339---
340340--- prop> let types = (x :: Int, y :: String) in modify fstL id (x, y) == (x, y)
341341---
342342--- prop> let types = (x :: Int, y :: String) in modify sndL id (x, y) == (x, y)
343343-modify ::
344344- Lens s t a b
345345- -> (a -> b)
346346- -> s
347347- -> t
348348-modify =
349349- error "todo: modify"
350350-351351--- | An alias for @modify@.
352352-(%~) ::
353353- Lens s t a b
354354- -> (a -> b)
355355- -> s
356356- -> t
357357-(%~) =
358358- modify
359359-360360-infixr 4 %~
361361-362362--- |
363363---
364364--- >>> fstL .~ 1 $ (0 :: Int, "abc")
365365--- (1,"abc")
366366---
367367--- >>> sndL .~ 1 $ ("abc", 0 :: Int)
368368--- ("abc",1)
369369---
370370--- prop> let types = (x :: Int, y :: String) in set fstL (x, y) z == (fstL .~ z $ (x, y))
371371---
372372--- prop> let types = (x :: Int, y :: String) in set sndL (x, y) z == (sndL .~ z $ (x, y))
373373-(.~) ::
374374- Lens s t a b
375375- -> b
376376- -> s
377377- -> t
378378-(.~) =
379379- error "todo: (.~)"
380380-381381-infixl 5 .~
382382-383383--- |
384384---
385385--- >>> fmodify fstL (+) (5 :: Int, "abc") 8
386386--- (13,"abc")
387387---
388388--- >>> fmodify fstL (\n -> bool Nothing (Just (n * 2)) (even n)) (10, "abc")
389389--- Just (20,"abc")
390390---
391391--- >>> fmodify fstL (\n -> bool Nothing (Just (n * 2)) (even n)) (11, "abc")
392392--- Nothing
393393-fmodify ::
394394- Functor f =>
395395- Lens s t a b
396396- -> (a -> f b)
397397- -> s
398398- -> f t
399399-fmodify =
400400- error "todo: fmodify"
401401-402402--- |
403403---
404404--- >>> fstL |= Just 3 $ (7, "abc")
405405--- Just (3,"abc")
406406---
407407--- >>> (fstL |= (+1) $ (3, "abc")) 17
408408--- (18,"abc")
409409-(|=) ::
410410- Functor f =>
411411- Lens s t a b
412412- -> f b
413413- -> s
414414- -> f t
415415-(|=) =
416416- error "todo: (|=)"
417417-418418-infixl 5 |=
419419-420420--- |
421421---
422422--- >>> modify fstL (*10) (3, "abc")
423423--- (30,"abc")
424424-fstL ::
425425- Lens (a, x) (b, x) a b
426426-fstL =
427427- error "todo: fstL"
428428-429429--- |
430430---
431431--- >>> modify sndL (++ "def") (13, "abc")
432432--- (13,"abcdef")
433433-sndL ::
434434- Lens (x, a) (x, b) a b
435435-sndL =
436436- error "todo: sndL"
437437-438438--- |
439439---
440440--- >>> get (mapL 3) (Map.fromList (map (\c -> (ord c - 96, c)) ['a'..'d']))
441441--- Just 'c'
442442---
443443--- >>> get (mapL 33) (Map.fromList (map (\c -> (ord c - 96, c)) ['a'..'d']))
444444--- Nothing
445445---
446446--- >>> set (mapL 3) (Map.fromList (map (\c -> (ord c - 96, c)) ['a'..'d'])) (Just 'X')
447447--- fromList [(1,'a'),(2,'b'),(3,'X'),(4,'d')]
448448---
449449--- >>> set (mapL 33) (Map.fromList (map (\c -> (ord c - 96, c)) ['a'..'d'])) (Just 'X')
450450--- fromList [(1,'a'),(2,'b'),(3,'c'),(4,'d'),(33,'X')]
451451---
452452--- >>> set (mapL 3) (Map.fromList (map (\c -> (ord c - 96, c)) ['a'..'d'])) Nothing
453453--- fromList [(1,'a'),(2,'b'),(4,'d')]
454454---
455455--- >>> set (mapL 33) (Map.fromList (map (\c -> (ord c - 96, c)) ['a'..'d'])) Nothing
456456--- fromList [(1,'a'),(2,'b'),(3,'c'),(4,'d')]
457457-mapL ::
458458- Ord k =>
459459- k
460460- -> Lens (Map k v) (Map k v) (Maybe v) (Maybe v)
461461-mapL =
462462- error "todo: mapL"
463463-464464--- |
465465---
466466--- >>> get (setL 3) (Set.fromList [1..5])
467467--- True
468468---
469469--- >>> get (setL 33) (Set.fromList [1..5])
470470--- False
471471---
472472--- >>> set (setL 3) (Set.fromList [1..5]) True
473473--- fromList [1,2,3,4,5]
474474---
475475--- >>> set (setL 3) (Set.fromList [1..5]) False
476476--- fromList [1,2,4,5]
477477---
478478--- >>> set (setL 33) (Set.fromList [1..5]) True
479479--- fromList [1,2,3,4,5,33]
480480---
481481--- >>> set (setL 33) (Set.fromList [1..5]) False
482482--- fromList [1,2,3,4,5]
483483-setL ::
484484- Ord k =>
485485- k
486486- -> Lens (Set.Set k) (Set.Set k) Bool Bool
487487-setL =
488488- error "todo: setL"
489489-490490--- |
491491---
492492--- >>> get (compose fstL sndL) ("abc", (7, "def"))
493493--- 7
494494---
495495--- >>> set (compose fstL sndL) ("abc", (7, "def")) 8
496496--- ("abc",(8,"def"))
497497-compose ::
498498- Lens s t a b
499499- -> Lens q r s t
500500- -> Lens q r a b
501501-compose =
502502- error "todo: compose"
503503-504504--- | An alias for @compose@.
505505-(|.) ::
506506- Lens s t a b
507507- -> Lens q r s t
508508- -> Lens q r a b
509509-(|.) =
510510- compose
511511-512512-infixr 9 |.
513513-514514--- |
515515---
516516--- >>> get identity 3
517517--- 3
518518---
519519--- >>> set identity 3 4
520520--- 4
521521-identity ::
522522- Lens a b a b
523523-identity =
524524- error "todo: identity"
525525-526526--- |
527527---
528528--- >>> get (product fstL sndL) (("abc", 3), (4, "def"))
529529--- ("abc","def")
530530---
531531--- >>> set (product fstL sndL) (("abc", 3), (4, "def")) ("ghi", "jkl")
532532--- (("ghi",3),(4,"jkl"))
533533-product ::
534534- Lens s t a b
535535- -> Lens q r c d
536536- -> Lens (s, q) (t, r) (a, c) (b, d)
537537-product =
538538- error "todo: product"
539539-540540--- | An alias for @product@.
541541-(***) ::
542542- Lens s t a b
543543- -> Lens q r c d
544544- -> Lens (s, q) (t, r) (a, c) (b, d)
545545-(***) =
546546- product
547547-548548-infixr 3 ***
549549-550550--- |
551551---
552552--- >>> get (choice fstL sndL) (Left ("abc", 7))
553553--- "abc"
554554---
555555--- >>> get (choice fstL sndL) (Right ("abc", 7))
556556--- 7
557557---
558558--- >>> set (choice fstL sndL) (Left ("abc", 7)) "def"
559559--- Left ("def",7)
560560---
561561--- >>> set (choice fstL sndL) (Right ("abc", 7)) 8
562562--- Right ("abc",8)
563563-choice ::
564564- Lens s t a b
565565- -> Lens q r a b
566566- -> Lens (Either s q) (Either t r) a b
567567-choice =
568568- error "todo: choice"
569569-570570--- | An alias for @choice@.
571571-(|||) ::
572572- Lens s t a b
573573- -> Lens q r a b
574574- -> Lens (Either s q) (Either t r) a b
575575-(|||) =
576576- choice
577577-578578-infixr 2 |||
579579-580580-----
581581-582582-type Lens' a b =
583583- Lens a a b b
584584-585585-cityL ::
586586- Lens' Locality String
587587-cityL p (Locality c t y) =
588588- fmap (\c' -> Locality c' t y) (p c)
589589-590590-stateL ::
591591- Lens' Locality String
592592-stateL p (Locality c t y) =
593593- fmap (\t' -> Locality c t' y) (p t)
594594-595595-countryL ::
596596- Lens' Locality String
597597-countryL p (Locality c t y) =
598598- fmap (\y' -> Locality c t y') (p y)
599599-600600-streetL ::
601601- Lens' Address String
602602-streetL p (Address t s l) =
603603- fmap (\t' -> Address t' s l) (p t)
604604-605605-suburbL ::
606606- Lens' Address String
607607-suburbL p (Address t s l) =
608608- fmap (\s' -> Address t s' l) (p s)
609609-610610-localityL ::
611611- Lens' Address Locality
612612-localityL p (Address t s l) =
613613- fmap (\l' -> Address t s l') (p l)
614614-615615-ageL ::
616616- Lens' Person Int
617617-ageL p (Person a n d) =
618618- fmap (\a' -> Person a' n d) (p a)
619619-620620-nameL ::
621621- Lens' Person String
622622-nameL p (Person a n d) =
623623- fmap (\n' -> Person a n' d) (p n)
624624-625625-addressL ::
626626- Lens' Person Address
627627-addressL p (Person a n d) =
628628- fmap (\d' -> Person a n d') (p d)
629629-630630-intAndIntL ::
631631- Lens' (IntAnd a) Int
632632-intAndIntL p (IntAnd n a) =
633633- fmap (\n' -> IntAnd n' a) (p n)
634634-635635--- lens for polymorphic update
636636-intAndL ::
637637- Lens (IntAnd a) (IntAnd b) a b
638638-intAndL p (IntAnd n a) =
639639- fmap (\a' -> IntAnd n a') (p a)
640640-641641--- |
642642---
643643--- >>> get (suburbL |. addressL) fred
644644--- "Fredville"
645645---
646646--- >>> get (suburbL |. addressL) mary
647647--- "Maryland"
648648-getSuburb ::
649649- Person
650650- -> String
651651-getSuburb =
652652- error "todo: getSuburb"
653653-654654--- |
655655---
656656--- >>> setStreet fred "Some Other St"
657657--- Person 24 "Fred" (Address "Some Other St" "Fredville" (Locality "Fredmania" "New South Fred" "Fredalia"))
658658---
659659--- >>> setStreet mary "Some Other St"
660660--- Person 28 "Mary" (Address "Some Other St" "Maryland" (Locality "Mary Mary" "Western Mary" "Maristan"))
661661-setStreet ::
662662- Person
663663- -> String
664664- -> Person
665665-setStreet =
666666- error "todo: setStreet"
667667-668668--- |
669669---
670670--- >>> getAgeAndCountry (fred, maryLocality)
671671--- (24,"Maristan")
672672---
673673--- >>> getAgeAndCountry (mary, fredLocality)
674674--- (28,"Fredalia")
675675-getAgeAndCountry ::
676676- (Person, Locality)
677677- -> (Int, String)
678678-getAgeAndCountry =
679679- error "todo: getAgeAndCountry"
680680-681681--- |
682682---
683683--- >>> setCityAndLocality (fred, maryAddress) ("Some Other City", fredLocality)
684684--- (Person 24 "Fred" (Address "15 Fred St" "Fredville" (Locality "Some Other City" "New South Fred" "Fredalia")),Address "83 Mary Ln" "Maryland" (Locality "Fredmania" "New South Fred" "Fredalia"))
685685---
686686--- >>> setCityAndLocality (mary, fredAddress) ("Some Other City", maryLocality)
687687--- (Person 28 "Mary" (Address "83 Mary Ln" "Maryland" (Locality "Some Other City" "Western Mary" "Maristan")),Address "15 Fred St" "Fredville" (Locality "Mary Mary" "Western Mary" "Maristan"))
688688-setCityAndLocality ::
689689- (Person, Address) -> (String, Locality) -> (Person, Address)
690690-setCityAndLocality =
691691- error "todo: setCityAndLocality"
692692-693693--- |
694694---
695695--- >>> getSuburbOrCity (Left maryAddress)
696696--- "Maryland"
697697---
698698--- >>> getSuburbOrCity (Right fredLocality)
699699--- "Fredmania"
700700-getSuburbOrCity ::
701701- Either Address Locality
702702- -> String
703703-getSuburbOrCity =
704704- error "todo: getSuburbOrCity"
705705-706706--- |
707707---
708708--- >>> setStreetOrState (Right maryLocality) "Some Other State"
709709--- Right (Locality "Mary Mary" "Some Other State" "Maristan")
710710---
711711--- >>> setStreetOrState (Left fred) "Some Other St"
712712--- Left (Person 24 "Fred" (Address "Some Other St" "Fredville" (Locality "Fredmania" "New South Fred" "Fredalia")))
713713-setStreetOrState ::
714714- Either Person Locality
715715- -> String
716716- -> Either Person Locality
717717-setStreetOrState =
718718- error "todo: setStreetOrState"
719719-720720--- |
721721---
722722--- >>> modifyCityUppercase fred
723723--- Person 24 "Fred" (Address "15 Fred St" "Fredville" (Locality "FREDMANIA" "New South Fred" "Fredalia"))
724724---
725725--- >>> modifyCityUppercase mary
726726--- Person 28 "Mary" (Address "83 Mary Ln" "Maryland" (Locality "MARY MARY" "Western Mary" "Maristan"))
727727-modifyCityUppercase ::
728728- Person
729729- -> Person
730730-modifyCityUppercase =
731731- error "todo: modifyCityUppercase"
732732-733733--- |
734734---
735735--- >>> modifyIntAndLengthEven (IntAnd 10 "abc")
736736--- IntAnd 10 False
737737---
738738--- >>> modifyIntAndLengthEven (IntAnd 10 "abcd")
739739--- IntAnd 10 True
740740-modifyIntAndLengthEven ::
741741- IntAnd [a]
742742- -> IntAnd Bool
743743-modifyIntAndLengthEven =
744744- error "todo: modifyIntAndLengthEven"
745745-746746-----
747747-748748--- |
749749---
750750--- >>> over traverseLocality (map toUpper) (Locality "abc" "def" "ghi")
751751--- Locality "ABC" "DEF" "GHI"
752752-traverseLocality ::
753753- Traversal' Locality String
754754-traverseLocality =
755755- error "todo: traverseLocality"
756756-757757--- |
758758---
759759--- >>> over intOrIntP (*10) (IntOrIs 3)
760760--- IntOrIs 30
761761---
762762--- >>> over intOrIntP (*10) (IntOrIsNot "abc")
763763--- IntOrIsNot "abc"
764764-intOrIntP ::
765765- Prism' (IntOr a) Int
766766-intOrIntP =
767767- error "todo: intOrIntP"
768768-769769-intOrP ::
770770- Prism (IntOr a) (IntOr b) a b
771771-intOrP =
772772- error "todo: intOrP"
773773-774774--- |
775775---
776776--- >> over intOrP (even . length) (IntOrIsNot "abc")
777777--- IntOrIsNot False
778778---
779779--- >>> over intOrP (even . length) (IntOrIsNot "abcd")
780780--- IntOrIsNot True
781781---
782782--- >>> over intOrP (even . length) (IntOrIs 10)
783783--- IntOrIs 10
784784-intOrLengthEven ::
785785- IntOr [a]
786786- -> IntOr Bool
787787-intOrLengthEven =
788788- error "todo: intOrLengthEven"