Skip to content

Commit 9571d60

Browse files
committed
Changes per @garyb
1 parent 24e2ec0 commit 9571d60

File tree

3 files changed

+74
-34
lines changed

3 files changed

+74
-34
lines changed

src/Data/Lens/At.purs

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,22 @@ import Data.Newtype (unwrap)
1616
import Data.Lens (Lens', lens)
1717
import Data.Lens.Index (class Index)
1818

19-
20-
-- | `At` is useful for types like `Data.Map`:
21-
-- |
22-
-- | * The result of getting an element is a `Maybe a`.
23-
-- | * New elements can be added.
24-
-- | * Existing elements can be deleted.
19+
-- | Use an `At` lens if you want to add
20+
-- | new elements or delete old ones:
2521
-- |
2622
-- | ```purescript
27-
-- | > optic = at "key"
28-
-- | > view optic $ Map.singleton "key" "value"
29-
-- | (Just "value")
23+
-- | whole = Map.singleton "key" "value"
24+
-- | optic = at "key"
25+
-- |
26+
-- | view optic whole == Just "value"
3027
-- |
31-
-- | > set optic (Just "NEW") $ Map.singleton "key" "value"
32-
-- | (fromFoldable [(Tuple "key" "NEW")])
28+
-- | set optic (Just "NEW") whole == Map.singleton "key" "NEW"
3329
-- |
34-
-- | > set optic Nothing $ Map.singleton "key" "value"
35-
-- | (fromFoldable [])
30+
-- | set optic Nothing whole == Map.empty
3631
-- | ```
32+
-- |
33+
-- | If you want neither of those things, but only to view or change
34+
-- | an existing element, see `Data.Lens.Index`.
3735

3836
class Index m a b <= At m a b | m -> a, m -> b where
3937
at :: a -> Lens' m (Maybe b)

src/Data/Lens/Index.purs

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,32 @@ import Data.Set as S
1515
import Data.StrMap as SM
1616
import Data.Traversable (traverse)
1717

18-
-- | `Index` is useful when a focus element might not be present.
19-
-- | It allows you to `set` an existing focus element, but you cannot add a
20-
-- | new one or delete an old one.
21-
-- |
18+
-- | Use an `Index` optic on types where:
19+
-- | 1. The focus element might not be present.
20+
-- | 2. You either cannot or do not want to add new elements or delete existing ones.
21+
-- |
22+
-- | `Array` is a typical example:
23+
-- |
2224
-- | ```purescript
23-
-- |> optic = ix 1
24-
-- |> preview optic [0, 1, 2]
25-
-- |(Just 1)
25+
-- | preview (ix 1) [0, 1, 2] == Just 1
26+
-- |
27+
-- | set (ix 1) 8888 [0, 1, 2] == [0,8888,2]
28+
-- | ```
2629
-- |
27-
-- |> set optic 8888 [0, 1, 2]
28-
-- |[0,8888,2]
30+
-- | Note the use of `preview` rather `view`.
31+
-- |
32+
-- | Another common use is a `Map` that you don't want to either grow or shrink:
2933
-- |
30-
-- |-- Note that `Index` lenses work with many types:
31-
-- |> over optic negate $ Map.singleton 1 8888
32-
-- |(fromFoldable [(Tuple 1 -8888)])
34+
-- | ```purescript
35+
-- | (set (ix 1) 8888 $ Map.singleton 1 2) == Map.singleton 1 8888
36+
-- |
37+
-- | (set (ix 1) 8888 $ Map.empty) == Map.empty
3338
-- | ```
39+
-- |
40+
-- | Note the second line: an attempt to `set` a missing focus element
41+
-- | leaves the original whole unchanged.
42+
-- |
43+
-- | If you *do* want to add or delete elements, see `Data.Lens.At`.
3444

3545
class Index m a b | m -> a, m -> b where
3646
ix :: a -> Traversal' m b

src/Data/Lens/Types.purs

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,53 @@ import Data.Profunctor.Choice (class Choice)
2727
import Data.Profunctor.Closed (class Closed)
2828
import Data.Profunctor.Strong (class Strong)
2929

30-
-- | Given a type whose "focus element" can always be retrieved,
31-
-- | a lens provides a convenient way to view, get, and transform
30+
-- | Given a type whose "focus element" always exists,
31+
-- | a lens provides a convenient way to view, set, and transform
3232
-- | that element.
3333
-- |
34-
-- | `_2` is a Tuple-specific `Lens` available from `Data.Lens`, so:
34+
-- | For example, `_2` is a tuple-specific `Lens` available from `Data.Lens`, so:
3535
-- | ```purescript
36-
-- | > import Data.Lens
37-
-- | > over _2 String.length $ Tuple "ignore" "four"
38-
-- | (Tuple "ignore" 4)
36+
-- | over _2 String.length $ Tuple "ignore" "four" == Tuple "ignore" 4
3937
-- | ```
38+
-- | Note the result has a different type than the original tuple.
39+
-- | That is, the four `Lens` type variables have been narrowed to:
40+
-- |
41+
-- | * `s` is `Tuple String String`
42+
-- | * `t` is `Tuple String Int`
43+
-- | * `a` is `String`
44+
-- | * `b` is `Int`
45+
-- |
46+
-- | See `Data.Lens.Getter` and `Data.Lens.Setter` for functions and operators
47+
-- | frequently used with lenses.
48+
49+
4050
type Lens s t a b = forall p. Strong p => Optic p s t a b
4151

42-
-- | `Lens` allows `set` to change the type of the focus. Often, a
43-
-- | particular lens won't do that. This type alias declares that `set`
44-
-- | only changes values, not types.
52+
-- | `Lens'` is a specialization of `Lens`. An optic of type `Lens'`
53+
-- | can change only the value of its focus,
54+
-- | not its type. As an example, consider the `Lens` `_2`, which has this type:
55+
-- |
56+
-- | ```purescript
57+
-- | _2 :: forall s t a b. Lens (Tuple s a) (Tuple t b) a b
58+
-- | ```
59+
-- |
60+
-- | `_2` can produce a `Tuple Int String` from a `Tuple Int Int`:
61+
-- |
62+
-- | ```purescript
63+
-- | set _2 "NEW" (Tuple 1 2) == (Tuple 1 "NEW")
64+
-- | ```
65+
-- |
66+
-- | If we specialize `_2`'s type with `Lens'`, the following will not
67+
-- | type check:
68+
-- |
69+
-- | ```purescript
70+
-- | set (_2 :: Lens' (Tuple Int Int) Int) "NEW" (Tuple 1 2)
71+
-- | ^^^^^^^^^^^^^^^^^^^^^^^^^
72+
-- | ```
73+
-- |
74+
-- | See `Data.Lens.Getter` and `Data.Lens.Setter` for functions and operators
75+
-- | frequently used with lenses.
76+
4577
type Lens' s a = Lens s s a a
4678

4779
-- | A prism.

0 commit comments

Comments
 (0)