public
Last active

  • Download Gist
Markus Hauck revised this gist . 1 changed file with 2 additions and 2 deletions. View gist @ cebe6e1
gistfile1.md
4 
... 410 411 412 413   414 415 416 ... 410 411 412   413 414 415 416
@@ -410,7 +410,7 @@ Yep! It's just `toListOf`.
>>> [1,2,3] ^.. items
[1,2,3]
-# What else can we do with Traversals? [How do they related to Prisms/Lenses?]
+# What else can we do with Traversals? [How do they relate to Prisms/Lenses?]
We can get just the first target.
... 578 579 580 581     ... 578 579 580     581
@@ -578,4 +578,4 @@ But for now, go get yourself a peanut butter and marmalade sandwich.
---
-With help from penguinland.
\ No newline at end of file
+With help from penguinland.
Markus Hauck revised this gist . No changes. View gist @ c374a95
Markus Hauck revised this gist . No changes. View gist @ eee5d5f
Markus Hauck revised this gist . No changes. View gist @ 834c844
Markus Hauck revised this gist . No changes. View gist @ bf0970b
Markus Hauck revised this gist . No changes. View gist @ 784c183
Markus Hauck revised this gist . 1 changed file with 1 addition and 1 deletion. View gist @ e57787c
gistfile1.md
2 
... 366 367 368 369   370 371 372 ... 366 367 368   369 370 371 372
@@ -366,7 +366,7 @@ What if we make `Prism'`s that focus on particular branches of `String`?
>>> preview _ParseFalse "True"
Nothing
- >>> review True
+ >>> review _ParseTrue True
"True"
This is how printer-parsers can sometimes be valid Prisms.
Markus Hauck revised this gist . 1 changed file with 22 additions and 22 deletions. View gist @ b97b7fe
gistfile1.md
44 
... 10 11 12 13   14 15 16 17   18 19 20 ... 10 11 12   13 14 15 16   17 18 19 20
@@ -10,11 +10,11 @@ Lenses let you apply some of the power of libraries like `hxt` to all data types
Eventually, you can use lenses to bring things like record syntax, lookups in lists or maps, pattern matching, `Data.Traversable`, scrap your boilerplate, the `newtype` library, and all kinds of type isomorphisms all together under the same mental model.
-The end result is a way to efficiently contruct and manipulate "methods of poking around inside things" as simple first-class values.
+The end result is a way to efficiently construct and manipulate "methods of poking around inside things" as simple first-class values.
# Okay, what is a Lens?
-A lens is a first-class reference to a subpart of some data type. For instnace, we have `_1` which is the lens that "focuses on" the first element of a pair. Given a lens there are essentially three things you might want to do
+A lens is a first-class reference to a subpart of some data type. For instance, we have `_1` which is the lens that "focuses on" the first element of a pair. Given a lens there are essentially three things you might want to do
1. View the subpart
2. Modify the whole by changing the subpart
... 77 78 79 80   81 82 83 ... 77 78 79   80 81 82 83
@@ -77,7 +77,7 @@ Yeah, here are the lens laws again written using actual code. Below, `l` is any
Don't expect to be able to read the code yet, but here's an example from `lens-aeson` which queries and modifies JSON data.
- -- Returns all of the major versions of an
+ -- Returns all of the major versions of an
-- array of JSON objects.
someString ^.. _JSON -- a parser/printer prism
. _Array -- another prism
... 118 119 120 121   122 123 124 ... 118 119 120   121 122 123 124
@@ -118,7 +118,7 @@ I'd show you `_1` but it's not a great example of an understandable type. It use
{-# LANGUAGE TemplateHaskell #-}
type Degrees = Double
- type Latitute = Degrees
+ type Latitude = Degrees
type Longitude = Degrees
data Meetup = Meetup { _name :: String, _location :: (Latitude, Longitude) }
... 126 127 128 129   130 131 132 ... 126 127 128   129 130 131 132
@@ -126,7 +126,7 @@ I'd show you `_1` but it's not a great example of an understandable type. It use
Let's assume we have lenses `name` and `location` which focus on the slots `_name` and `_location` respectively. The underscores are a convention only, but you see them a lot because the Template Haskell magic going on in `makeLenses` will automatically make `name` and `location` if use underscores like that.
-The type of these lenses is
+The type of these lenses is
>>> :info name
name :: Lens Meetup Meetup String String
... 154 155 156 157   158 159 160 ... 154 155 156   157 158 159 160
@@ -154,7 +154,7 @@ Yup, if we've got a `Lens s x` and another lens `Lens x a` we can stick them tog
la :: Lens s x
lb :: Lens x a
-
+
la . lb :: Lens s a
Or, more concretely.
... 164 165 166 167   168 169 170 ... 164 165 166   167 168 169 170
@@ -164,7 +164,7 @@ Or, more concretely.
# Lenses compose backwards. Can't we make (.) behave like functions?
-You're right, we could. We don't for various reasons, but the intution is right. Lenses should combine just like functions. One thing that's important about that is `id` can either pre- or post- compose with any lens without affecting it.
+You're right, we could. We don't for various reasons, but the intuition is right. Lenses should combine just like functions. One thing that's important about that is `id` can either pre- or post- compose with any lens without affecting it.
forall $ \lens -> lens . id == lens
forall $ \lens -> id . lens == lens
... 225 226 227 228   229 230 231 ... 225 226 227   228 229 230 231
@@ -225,7 +225,7 @@ Sometimes we get new operators by augmenting tried and true operators like `(&&)
(<>~) :: Monoid m => Lens' s m -> m -> (s -> s)
lens <>~ m = lens %~ (m <>)
-## What about (^)? Does that show up anywhere else?
+## What about (^?) Does that show up anywhere else?
Yes, but we have to talk about `Prism`s and `Traversal`s first.
... 292 293 294 295   296 297 298 ... 292 293 294   295 296 297 298
@@ -292,7 +292,7 @@ Whenever we can do that, we can make a lens that focuses just on that subpart.
That's how prisms are dual to lenses. They select just one branch to go down.
preview :: Prism' s a -> s -> Maybe a
-
+
Which also lets us "go back up" that one branch.
review :: Prism' s a -> a -> s
... 327 328 329 330   331 332 333 ... 327 328 329   330 331 332 333
@@ -327,7 +327,7 @@ Yep, `(^?)` is like `(^.)` for `Prism'`s.
# Are there any other interesting Prisms? [Printer/Parsers]
-Here's a simple one. We can deconstruct `[]`s using `Prism'`s.
+Here's a simple one. We can deconstruct `[]`s using `Prism'`s.
_Cons :: Prism' [a] (a, [a])
... 338 339 340 341   342 343 344 ... 338 339 340   341 342 343 344
@@ -338,7 +338,7 @@ Here's a simple one. We can deconstruct `[]`s using `Prism'`s.
Just (1, [2,3])
_Nil :: Prism' [a] ()
-
+
>>> preview _Nil []
Just ()
... 385 386 387 388   389 390 391 ... 385 386 387   388 389 390 391
@@ -385,7 +385,7 @@ A very simple `Traversal'` traverses all of the items in a list.
In fact, `Traversal'`s are intimately related to lists since if we have a list we also may have either 1, or 0, or many elements. That's one way to `view` a `Traversal`.
toListOf items :: [a] -> [a]
-
+
>>> toListOf items [1,2,3]
[1,2,3]
... 420 421 422 423 424     425 426 427 ... 420 421 422     423 424 425 426 427
@@ -420,8 +420,8 @@ We can get just the first target.
Or the last target
lastOf :: Traversal' s a -> Maybe a
-
- >>> lastOf items [1,2,3]
+
+ >>> lastOf items [1,2,3]
Just 3
## Why does it use Maybe?
... 441 442 443 444   445 446 447 ... 441 442 443   444 445 446 447
@@ -441,7 +441,7 @@ Nope, `preview` just handles access that focuses on either 0 or 1 targets.
Actually, yes, but you might be in for a surprise.
>>> view items "hello world"
-
+
<interactive>:56:6:
No instance for (Data.Monoid.Monoid Char)
arising from a use of `items'
... 493 494 495 496   497 498 499 ... 493 494 495   496 497 498 499
@@ -493,7 +493,7 @@ That's not even the best part yet.
We can compose `Lens`es and `Prism`s and `Traversal`s all together and the types will "just work out". Admittedly at this point all that means is that compositions of Lenses are Lenses, compositions of Prisms are Prisms, and everything else is a Traversal.
-But there are other things in this subtyping hierachy, like `Iso`s.
+But there are other things in this subtyping hierarchy, like `Iso`s.
# What are Isos?
... 523 524 525 526   527 528 529 ... 523 524 525   526 527 528 529
@@ -523,7 +523,7 @@ They can compose on either end of a lens or a prism and the result is a lens or
How about between `Maybe` and `Either ()`?
someIso :: Iso' (Maybe a) (Either () a)
-
+
>>> Just "hi" ^. someIso
Right "hi"
... 545 546 547 548   549 550 551 552 553   554 555 556 557     558 559 560 561 562 563 564   565 566 567 ... 545 546 547   548 549 550 551 552   553 554 555     556 557 558 559 560 561 562 563   564 565 566 567
@@ -545,23 +545,23 @@ Also kind of boring. [How about between an XML tree treating element names as st
Element (QName { qnPrefix = Just "foaf"
, qnLocalPart = "Person"
- })
+ })
[ (QName { qnPrefix = Just "foaf"
, qnLocalPart = "name"
}
,"Ernest")
- ]
+ ]
[]
- >>> Element "foaf:Person" [("foaf:name", "Ernest")] [] ^? qualified
- . attributes
+ >>> Element "foaf:Person" [("foaf:name", "Ernest")] [] ^? qualified
+ . attributes
. _head . _1 . localPart
Just "name"
# What is "from" doing there? [Iso Laws]
`from` "turns an iso around". Since `Iso`s are equivalences they're symmetric and we can treat them as maps in both directions between types. In fact, the `Iso` laws stated above are just that for any iso, `iso`
-
+
view (iso . from iso) == id
view (from iso . iso) == id
Markus Hauck renamed this gist . 1 changed file with 0 additions and 0 deletions. View gist @ 0953f28
gistfile1.txt → gistfile1.md
File renamed without changes
Markus Hauck created this gist . View gist @ 84db2b8
gistfile1.txt
581 
...                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             ... 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581  
@@ -0,0 +1,581 @@
+# What is lens?
+
+`lens` is a package which provides the type synonym `Lens` which is one of a few implementations of the concept of lenses, or functional references. `lens` also provides a number of generalizations of lenses including `Prism`s, `Traversal`s, `Iso`s, and `Fold`s.
+
+# Why do I care?
+
+Lenses and their cousins are a way of declaring how to focus deeply into a complex structure. They form a combinator library with sensible, general behavior for things like composition, failure, multiplicity, transformation, and representation.
+
+Lenses let you apply some of the power of libraries like `hxt` to all data types in all programs that you write. As this comparison suggests, the initial steps might be very complicated, but, unlike `hxt`, lenses are ubiquitous enough to make learning the complexity pay off over time.
+
+Eventually, you can use lenses to bring things like record syntax, lookups in lists or maps, pattern matching, `Data.Traversable`, scrap your boilerplate, the `newtype` library, and all kinds of type isomorphisms all together under the same mental model.
+
+The end result is a way to efficiently contruct and manipulate "methods of poking around inside things" as simple first-class values.
+
+# Okay, what is a Lens?
+
+A lens is a first-class reference to a subpart of some data type. For instnace, we have `_1` which is the lens that "focuses on" the first element of a pair. Given a lens there are essentially three things you might want to do
+
+1. View the subpart
+2. Modify the whole by changing the subpart
+3. Combine this lens with another lens to look even deeper
+
+The first and the second give rise to the idea that lenses are getters and setters like you might have on an object. This intuition is often morally correct and it helps to explain the lens laws.
+
+# The lens laws?
+
+Yep. Like the monad laws, these are expectations you should have about lenses. Lenses that violate them are *weird*. Here they are
+
+1. Get-Put: If you modify something by changing its subpart to exactly what it was before... then nothing happens
+2. Put-Get: If you modify something by inserting a particular subpart and then viewing the result... you'll get back exactly that subpart
+3. Put-Put: If you modify something by inserting a particular subpart `a`, and then modify it again inserting a different subpart `b`... it's exactly as if you only did the second step.
+
+Lenses that follow these laws are called "very well-behaved".
+
+# What does it look like to use a lens?
+
+Well, let's look at `_1` again, the lens focusing on the first part of a tuple. We view the first part of the tuple using `view`
+
+ >>> view _1 ("goal", "chaff")
+ "goal"
+
+ >>> forall $ \tuple -> view _1 tuple == fst tuple
+ True
+
+We modify `_1`'s focused subpart by using `over` (mnemonic: we're mapping our modification "over" the focal point of `_1`).
+
+ >>> over _1 (++ "!!!") ("goal", "the crowd goes wild")
+ ("goal!!!", "the crowd goes wild")
+
+ >>> forall $ \tuple -> over _1 f tuple == (\(fst, snd) -> (f fst, snd)) tuple
+ True
+
+As a special case of modification, we can set the subpart to be a new subpart. This is called `set`
+
+ >>> set _1 "set" ("game", "match")
+ ("set", "match")
+
+ >>> forall $ \tuple -> set _1 x tuple = over _1 (const x) tuple
+ True
+
+## Any more examples?
+
+Yeah, here are the lens laws again written using actual code. Below, `l` is any "very well-behaved" lens.
+
+ -- Get-Put
+ >>> forall $ \whole -> set l (view l whole) whole == whole
+ True
+
+ -- Put-Get
+ >>> forall $ \whole part -> view l (set l part whole) == part
+ True
+
+ -- Put-Put
+ >>> forall $ \whole part1 part2 -> set l part2 (set l part1) whole = set l part2 whole
+
+# What are some large scale, practical examples of lens?
+
+Don't expect to be able to read the code yet, but here's an example from `lens-aeson` which queries and modifies JSON data.
+
+ -- Returns all of the major versions of an
+ -- array of JSON objects.
+ someString ^.. _JSON -- a parser/printer prism
+ . _Array -- another prism
+ . traverse -- a traversal (using Data.Traversable on Aeson's Vector)
+ . _Object -- another another prism
+ . ix "version" -- a traversal across a "map-like thing"
+ . _1 -- a lens into a tuple (major, minor, patch)
+
+ -- Increments all of the versions above
+ someString & _JSON
+ . _Array
+ . traverse
+ . _Object
+ . ix "version"
+ . _1
+ %~ succ -- apply a function to our deeply focused lens
+
+ -- We can factor out the lens
+ allVersions :: Traversal' ByteString Int
+ allVersions = _JSON . _Array . traverse . _Object . ix "version" . _1
+
+ -- and then rewrite the two examples quickly
+
+ someString ^.. allVersions
+ someString & allVersions %~ succ
+
+
+ -- Because lenses, prisms, traversals, are all first class in Haskell!
+
+# Wait a second, GHCi is telling me the types of these things are absurd!
+
+Yeah, sorry about that. "It'll make sense eventually", but the types start out tricky.
+
+Try to look at the type synonyms only. We can use `:info` to make sure that GHCi tells us the type synonym instead of the really funky fully expanded types.
+
+I'd show you `_1` but it's not a great example of an understandable type. It uses some weird extra machinery. Instead, how about an example.
+
+ {-# LANGUAGE TemplateHaskell #-}
+
+ type Degrees = Double
+ type Latitute = Degrees
+ type Longitude = Degrees
+
+ data Meetup = Meetup { _name :: String, _location :: (Latitude, Longitude) }
+ makeLenses ''Meetup
+
+Let's assume we have lenses `name` and `location` which focus on the slots `_name` and `_location` respectively. The underscores are a convention only, but you see them a lot because the Template Haskell magic going on in `makeLenses` will automatically make `name` and `location` if use underscores like that.
+
+The type of these lenses is
+
+ >>> :info name
+ name :: Lens Meetup Meetup String String
+
+ >>> :info location
+ age :: Lens Meetup Meetup (Latitude, Longitude) (Latitude, Longitude)
+
+ >>> :type location
+ age :: Functor f => ((Latitude, Longitude) -> f (Latitude, Longitude)) -> (Meetup -> f Meetup)
+
+ -- whoops! Ignore that for now please
+
+# Four type parameters? Isn't that a bit much?
+
+You're right, we'll use the simplified forms for now. This is highly recommended until you get the hang of things. The simplified types are appended with apostrophes. Now the types of `name` and `location` are
+
+ name :: Lens' Meetup String
+ age :: Lens' Meetup (Latitude, Longitude)
+
+These types tell us that, for instance, the `name` lens focuses *from* a `Meetup` and *to* a `String`. Generally we write `Lens' s a` and throughout the documentation `s` and `t` tend to be where a lens is focusing *from* and `a` or `b` tend to be where the lens is focusing *to*.
+
+# Okay, that makes sense. Didn't you say we can compose lenses?
+
+Yup, if we've got a `Lens s x` and another lens `Lens x a` we can stick them together to get `Lens s a`. Strangely, we just use regular old `(.)` to do it.
+
+ la :: Lens s x
+ lb :: Lens x a
+
+ la . lb :: Lens s a
+
+Or, more concretely.
+
+ meetupLat = location . _1 :: Lens Meetup Latitude
+ meetupLon = location . _2 :: Lens Meetup Longitude
+
+# Lenses compose backwards. Can't we make (.) behave like functions?
+
+You're right, we could. We don't for various reasons, but the intution is right. Lenses should combine just like functions. One thing that's important about that is `id` can either pre- or post- compose with any lens without affecting it.
+
+ forall $ \lens -> lens . id == lens
+ forall $ \lens -> id . lens == lens
+
+(N.B. If you're categorically inclined, lenses-with-apostrophes would form a `Category` if we did somehow reverse the composition order.)
+
+## That's still pretty annoying
+
+It's true. On the bright side, lenses often feel a whole lot like OO-style slot access like `Person.name`. The reversed composition thing can be thought of as punning on that.
+
+ >>> Meetup { ... } ^. location . _1
+ 80.3 :: Latitude
+
+# What is that (^.)?
+
+Oh, it's just `view` written infix. Here's the Put-Get law again
+
+ >>> forall $ \lens whole part -> (set lens part whole) ^. lens == part
+ True
+
+## Actually there are a whole lot of operators in lens
+
+Yup, some people find them convenient.
+
+# Actually there are a WHOLE LOT of operators in lens---over 100
+
+Very convenient! But that *is* a lot. To make it bearable, there are some tricks for remembering them.
+
+1. Operators that begin with `^` are kinds of `view`s. The only example we've seen so far is `(^.)` which is... well, it's just `view` exactly.
+2. Operators that end with `~` are like `over` or `set`. In fact, `(.~) == set` and `(%~)` is `over`.
+3. Operators that have `.` in them are usually somehow "basic"
+4. Operators that have `%` in them usually take functions
+5. Operators that have `=` in them are just like their cousins where `=` is replaced by `~`, but instead of taking the whole object as an argument, they apply their modifications in a `State` monad.
+
+## Is that really worth it?
+
+Maybe. Who knows!
+
+If you don't like them, then all of the operators have regular named functions as well.
+
+## ... Some examples would be nice
+
+Ok.
+
+ (.~) :: Lens' s a -> a -> (s -> s)
+ (.=) :: Lens' s a -> a -> State s ()
+ (%~) :: Lens' s a -> (a -> a) -> (s -> s)
+ (%=) :: Lens' s a -> (a -> a) -> State s ()
+
+Sometimes we get new operators by augmenting tried and true operators like `(&&)` with `~` and `=`
+
+ (&&~) :: Lens' s Bool -> Bool -> (s -> s)
+ (&&=) :: Lens' s Bool -> Bool -> State s ()
+
+ lens &&~ bool = lens %~ (bool &&)
+ lens &&= bool = lens %= (bool &&)
+
+ (<>~) :: Monoid m => Lens' s m -> m -> (s -> s)
+ lens <>~ m = lens %~ (m <>)
+
+## What about (^)? Does that show up anywhere else?
+
+Yes, but we have to talk about `Prism`s and `Traversal`s first.
+
+# Okay. What are Prisms?
+
+They're like lenses for sum types.
+
+## What does that mean?
+
+Well, what happens if we try to make lenses for a sum type?
+
+ -- This doesn't work... or exist
+ _left :: Lens' (Either a b) a
+
+ >>> view _left (Left ())
+ () -- okay, I buy that
+
+ >>> view _left (Right ())
+ error! -- oh, there's no subpart there
+
+`Prism`s are kind of like `Lens`es that can fail or miss.
+
+## So we use Maybe instead, right?
+
+We could try that.
+
+ _left :: Lens' (Either a b) (Maybe a)
+
+ >>> view _left (Left ())
+ Just ()
+
+ >>> view _left (Right ())
+ Nothing
+
+But it doesn't compose well.
+
+ _left . name :: Lens (Either Meetup Meetup) ??? -- String? Maybe String?
+
+We'd need a `Lens` that looks into `Maybe`:
+
+ _just :: Lens' (Maybe a) (Maybe a)
+ _just = id
+
+Oh. That doesn't get us anywhere. Let's start over.
+
+# Okay. What are Prisms? (Take Two)
+
+Prisms are the duals of lenses. While lenses pick apart some subpart of a product type like a tuple, prisms go down one branch of a sum type like `Either`... Or else they fail.
+
+## Right, a Lens splits out one subpart of a whole. A Prism takes one subbranch.
+
+Exactly!
+
+Think of a product type as being made of both a subpart and a "whole with a hole in it" where the subpart used to go.
+
+ product = (a, b)
+ subpart = a
+ whole-with-a-hole = \x -> (x, b)
+
+Whenever we can do that, we can make a lens that focuses just on that subpart.
+
+## A sum type can be broken into some particular subbranch and all-the-other-ones
+
+That's how prisms are dual to lenses. They select just one branch to go down.
+
+ preview :: Prism' s a -> s -> Maybe a
+
+Which also lets us "go back up" that one branch.
+
+ review :: Prism' s a -> a -> s
+
+For instance
+
+ _Left :: Prism' (Either a b) a
+
+ >>> preview _Left (Left "hi")
+ Just "hi"
+
+ >>> preview _Left (Right "hi")
+ Nothing
+
+ >>> review _Left "hi"
+ Left "hi"
+
+ _Just :: Prism' (Maybe a) a
+
+ >>> preview _Just (Just "hi")
+ Just "hi"
+
+ >>> review _Just "hi"
+ Just "hi"
+
+ >>> Left "hi" ^? _Left
+ Just "hi"
+
+## Oh, there's another (^)-like operator!
+
+Yep, `(^?)` is like `(^.)` for `Prism'`s.
+
+# Are there any other interesting Prisms? [Printer/Parsers]
+
+Here's a simple one. We can deconstruct `[]`s using `Prism'`s.
+
+ _Cons :: Prism' [a] (a, [a])
+
+ >>> preview _Cons []
+ Nothing
+
+ >>> preview _Cons [1,2,3]
+ Just (1, [2,3])
+
+ _Nil :: Prism' [a] ()
+
+ >>> preview _Nil []
+ Just ()
+
+ >>> preview _Nil [1,2,3]
+ Nothing
+
+Here's a strange one. `String` is a very strange sum type.
+
+## No it isn't. It's just a List again.
+
+But `Char` can be thought of as the sum of all characters. And if we "flatten" `Char` into `[]` we can think of `String` as being the "sum of all possible strings"
+
+ data String = "a" | "b" | "c" | "europe" | "curry" | "dosa" | "applejacks" ...
+
+## Okay, sure. Is that important?
+
+What if we make `Prism'`s that focus on particular branches of `String`?
+
+ _ParseTrue :: Prism' String Bool
+ _ParseFalse :: Prism' String Bool
+
+ >>> preview _ParseTrue "True"
+ Just True
+
+ >>> preview _ParseFalse "True"
+ Nothing
+
+ >>> review True
+ "True"
+
+This is how printer-parsers can sometimes be valid Prisms.
+
+# I think I understand Prisms now. What are Traversals?
+
+Traversals are Lenses which focus on multiple targets simultaneously. We actually don't know how many targets they might be focusing on: it could be exactly 1 (like a Lens) or maybe 0 (like a Prism) or 300.
+
+A very simple `Traversal'` traverses all of the items in a list.
+
+ items :: Traversal' [a] a
+ items = traverse -- from Data.Traversable, actually
+ -- this is our first implementation of anything in `lens`
+ -- but don't worry about it right now
+
+In fact, `Traversal'`s are intimately related to lists since if we have a list we also may have either 1, or 0, or many elements. That's one way to `view` a `Traversal`.
+
+ toListOf items :: [a] -> [a]
+
+ >>> toListOf items [1,2,3]
+ [1,2,3]
+
+## That's pretty boring.
+
+It is. We can define `items` for any `Traversable` though using the exact same definition.
+
+ items :: Traversable t => Traversal' (t a) a
+ items = traverse
+
+ flatten :: Tree a -> [a]
+ flatten = toListOf items
+
+## That's no big deal, though. It's just another way to use Data.Traversable
+
+For now, but `Traversal` will eventually show a close relationship with `Lens` and `Prism`.
+
+## Do we have another (^)-like operator for Traversals at least?
+
+Yep! It's just `toListOf`.
+
+ >>> [1,2,3] ^.. items
+ [1,2,3]
+
+# What else can we do with Traversals? [How do they related to Prisms/Lenses?]
+
+We can get just the first target.
+
+ firstOf :: Traversal' s a -> Maybe a
+ firstOf items :: Traversable t => t a -> Maybe a
+
+Or the last target
+
+ lastOf :: Traversal' s a -> Maybe a
+
+ >>> lastOf items [1,2,3]
+ Just 3
+
+## Why does it use Maybe?
+
+The `Traversal` could have no targets.
+
+## Is this like `preview`?
+
+Yeah, `firstOf` is `preview`.
+
+## But I thought preview was preview---and that it was specialized to Prisms?
+
+Nope, `preview` just handles access that focuses on either 0 or 1 targets.
+
+## Can I use view on Traversals too?
+
+Actually, yes, but you might be in for a surprise.
+
+ >>> view items "hello world"
+
+ <interactive>:56:6:
+ No instance for (Data.Monoid.Monoid Char)
+ arising from a use of `items'
+ Possible fix:
+ add an instance declaration for (Data.Monoid.Monoid Char)
+ In the first argument of `view', namely `items'
+ In the expression: view items "hello world"
+ In an equation for `it': it = view items "hello world"
+
+## What is Monoid doing here?
+
+It represents the notion of failure. It's just like that `Maybe` we tried to use earlier when investigating `Prism`.
+
+## So we can use view if our targets are Monoids?
+
+Yep. What do you think `["hello ", "world"] ^. items` gets us?
+
+## The Monoid product of the items---"hello world"
+
+Exactly! What about `[] ^. items`?
+
+## An ambiguous type error!
+
+Okay, yes. What about `[] ^. items :: String`?
+
+## The empty string, ""
+
+And `[] ^. items :: Monoid m => m`?
+
+## Whatever mempty is for m
+
+Bingo.
+
+# So, Traversals generalize Prisms and Lenses somehow?
+
+Yeah. It works because `Prism`, `Lens`, and `Traversal` are all just type synonyms---Those scary types that GHCi sometimes prints out actually do line up. That's a big reason why they're left in.
+
+# Is this subtyping?
+
+Kind of! That's what [the scary chart on the lens Hackage page](http://hackage.haskell.org/package/lens) shows.
+
+## But Haskell doesn't have subtyping
+
+It's a big clever hack, really. Without it there'd be completely separate combinators for `Lens`, `Prism`, `Traversal`, and all the other things in `lens` that we haven't talked about yet... even though they all end up with identical code at their core.
+
+That's not even the best part yet.
+
+# What's the best part about the subtyping hack?
+
+We can compose `Lens`es and `Prism`s and `Traversal`s all together and the types will "just work out". Admittedly at this point all that means is that compositions of Lenses are Lenses, compositions of Prisms are Prisms, and everything else is a Traversal.
+
+But there are other things in this subtyping hierachy, like `Iso`s.
+
+# What are Isos?
+
+Isos are isomorphisms, connections between types that are equivalent in every way.
+
+More concretely, an Iso is a forward mapping and a backward mapping such that the forward mapping inverts the backward mapping and the backward mapping inverts the forward mapping.
+
+ fw . bw = id
+ bw . fw = id
+
+(N.B. This is again exactly a `Category` isomorphism.)
+
+## Isos are in the lens subtyping hierarchy?
+
+Yep! They are more primitive than either `Lens` or `Prism`.
+
+If we think of a `Lens' s a` as a type which splits the product type `s` into its subpart `a` and the context of that subpart, `a -> s`, an `Iso` is a trivial lens where the context is just `id`.
+
+If we think of a `Prism' s a` as a type which splits the sum type `s` into a privileged branch and "all the other" branches then an `Iso` is a trivial `Prism` where there's just one branch and we're privileging exactly it.
+
+## How do Isos compose with Lenses and Prisms?
+
+They can compose on either end of a lens or a prism and the result is a lens or a prism respectively. Isos are "iso" (unchanging) because no matter where you put them in a lens pipeline they leave things as they were.
+
+# What are some example Isos?
+
+How about between `Maybe` and `Either ()`?
+
+ someIso :: Iso' (Maybe a) (Either () a)
+
+ >>> Just "hi" ^. someIso
+ Right "hi"
+
+That's a little boring. How about between strict and lazy `ByteString`s?
+
+ strict :: Iso' Lazy.ByteString Strict.ByteString
+
+ >>> "foobar" ^. strict
+ "foobar"
+
+ >>> "foobar" ^. strict . from strict
+ "foobar"
+
+Also kind of boring. [How about between an XML tree treating element names as strings and an XML tree treating element names as Qualified Names](http://hackage.haskell.org/package/hexpat-lens-0.0.7/docs/Text-XML-Expat-Lens-Names.html)?
+
+ qualified :: Iso' (Node String String) (Node (QName String) String)
+
+ >>> Element "foaf:Person" [("foaf:name", "Ernest")] [] ^. qualified
+
+ Element (QName { qnPrefix = Just "foaf"
+ , qnLocalPart = "Person"
+ })
+ [ (QName { qnPrefix = Just "foaf"
+ , qnLocalPart = "name"
+ }
+ ,"Ernest")
+ ]
+ []
+
+ >>> Element "foaf:Person" [("foaf:name", "Ernest")] [] ^? qualified
+ . attributes
+ . _head . _1 . localPart
+ Just "name"
+
+# What is "from" doing there? [Iso Laws]
+
+`from` "turns an iso around". Since `Iso`s are equivalences they're symmetric and we can treat them as maps in both directions between types. In fact, the `Iso` laws stated above are just that for any iso, `iso`
+
+ view (iso . from iso) == id
+ view (from iso . iso) == id
+
+## That's pretty cool
+
+`Iso`s are pretty cool. They're one of my favorite parts of `lens`.
+
+
+# What if I have any more questions?
+
+This list may grow over time. Please ask them and leave any comments.
+
+But for now, go get yourself a peanut butter and marmalade sandwich.
+
+---
+
+With help from penguinland.
\ No newline at end of file
Something went wrong with that request. Please try again.