Skip to content

Commit 569d819

Browse files
authored
Merge pull request #84 from marick/master
A start at documentation
2 parents d093f3b + 9dd4432 commit 569d819

File tree

4 files changed

+124
-18
lines changed

4 files changed

+124
-18
lines changed

src/Data/Lens/At.purs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module Data.Lens.At
33
, at
44
) where
55

6+
67
import Prelude
78

89
import Data.Identity (Identity(..))
@@ -15,6 +16,23 @@ import Data.Newtype (unwrap)
1516
import Data.Lens (Lens', lens)
1617
import Data.Lens.Index (class Index)
1718

19+
-- | `At` is a type class whose instances let you add
20+
-- | new elements or delete old ones from "container-like" types:
21+
-- |
22+
-- | ```purescript
23+
-- | whole = Map.singleton "key" "value"
24+
-- | optic = at "key"
25+
-- |
26+
-- | view optic whole == Just "value"
27+
-- |
28+
-- | set optic (Just "NEW") whole == Map.singleton "key" "NEW"
29+
-- |
30+
-- | set optic Nothing whole == Map.empty
31+
-- | ```
32+
-- |
33+
-- | If you don't want to add or delete, but only to view or change
34+
-- | an existing element, see `Data.Lens.Index`.
35+
1836
class Index m a b <= At m a b | m -> a, m -> b where
1937
at :: a -> Lens' m (Maybe b)
2038

src/Data/Lens/Index.purs

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

18+
-- | `Index` is a type class whose instances are optics used when:
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+
-- |
24+
-- | ```purescript
25+
-- | preview (ix 1) [0, 1, 2] == Just 1
26+
-- |
27+
-- | set (ix 1) 8888 [0, 1, 2] == [0,8888,2]
28+
-- | ```
29+
-- |
30+
-- | Note the use of `preview` rather `view`. That's because the optic is
31+
-- | a `Data.Lens.Traversal` tailored to the case where there's a single element
32+
-- | of interest.
33+
-- |
34+
-- | Another common use is a `Map` that you don't want to either grow or shrink:
35+
-- |
36+
-- | ```purescript
37+
-- | (set (ix "k") "new" $ Map.singleton "k" "old") == Map.singleton "k" "new"
38+
-- |
39+
-- | (set (ix "k") "new" $ Map.empty) == Map.empty
40+
-- | ```
41+
-- |
42+
-- | Note the second line: an attempt to `set` a missing focus element
43+
-- | leaves the original whole unchanged.
44+
-- |
45+
-- | If you *do* want to add or delete elements, see `Data.Lens.At`.
46+
1847
class Index m a b | m -> a, m -> b where
1948
ix :: a -> Traversal' m b
2049

src/Data/Lens/Lens.purs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,24 @@ import Data.Profunctor.Strong (first)
2424
import Data.Tuple (Tuple(..))
2525
import Data.Newtype(un)
2626

27-
lens' :: forall s t a b. (s -> Tuple a (b -> t)) -> Lens s t a b
28-
lens' to pab = dimap to (\(Tuple b f) -> f b) (first pab)
29-
3027
-- | Create a `Lens` from a getter/setter pair.
28+
-- |
29+
-- | ```purescript
30+
-- | > species = lens _.species $ _ {species = _}
31+
-- | > view species {species : "bovine"}
32+
-- | "bovine"
33+
-- |
34+
-- | > _2 = lens Tuple.snd $ \(Tuple keep _) new -> Tuple keep new
35+
-- | ```
36+
-- |
37+
-- | Note: `_2` is predefined in `Data.Lens.Tuple`.
38+
3139
lens :: forall s t a b. (s -> a) -> (s -> b -> t) -> Lens s t a b
3240
lens get set = lens' \s -> Tuple (get s) \b -> set s b
3341

42+
lens' :: forall s t a b. (s -> Tuple a (b -> t)) -> Lens s t a b
43+
lens' to pab = dimap to (\(Tuple b f) -> f b) (first pab)
44+
3445
withLens :: forall s t a b r. ALens s t a b -> ((s -> a) -> (s -> b -> t) -> r) -> r
3546
withLens l f = case l (Shop id \_ b -> b) of Shop x y -> f x y
3647

src/Data/Lens/Types.purs

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

30-
-- | A general-purpose Data.Lens.
31-
type Optic p s t a b = p a b -> p s t
32-
type Optic' p s a = Optic p s s a a
30+
-- | Given a type whose "focus element" always exists,
31+
-- | a lens provides a convenient way to view, set, and transform
32+
-- | that element.
33+
-- |
34+
-- | For example, `_2` is a tuple-specific `Lens` available from `Data.Lens`, so:
35+
-- | ```purescript
36+
-- | over _2 String.length $ Tuple "ignore" "four" == Tuple "ignore" 4
37+
-- | ```
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+
50+
type Lens s t a b = forall p. Strong p => Optic p s t a b
51+
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+
77+
type Lens' s a = Lens s s a a
78+
79+
-- | A prism.
80+
type Prism s t a b = forall p. Choice p => Optic p s t a b
81+
type Prism' s a = Prism s s a a
3382

3483
-- | A generalized isomorphism.
3584
type Iso s t a b = forall p. Profunctor p => Optic p s t a b
3685
type Iso' s a = Iso s s a a
3786

87+
-- | A traversal.
88+
type Traversal s t a b = forall p. Wander p => Optic p s t a b
89+
type Traversal' s a = Traversal s s a a
90+
91+
92+
93+
94+
-- | A general-purpose Data.Lens.
95+
type Optic p s t a b = p a b -> p s t
96+
type Optic' p s a = Optic p s s a a
97+
3898
type AnIso s t a b = Optic (Exchange a b) s t a b
3999
type AnIso' s a = AnIso s s a a
40100

41-
-- | A lens.
42-
type Lens s t a b = forall p. Strong p => Optic p s t a b
43-
type Lens' s a = Lens s s a a
44-
45101
type ALens s t a b = Optic (Shop a b) s t a b
46102
type ALens' s a = ALens s s a a
47103

@@ -52,17 +108,9 @@ type IndexedLens' i s a = IndexedLens i s s a a
52108
type AnIndexedLens i s t a b = IndexedOptic (Shop (Tuple i a) b) i s t a b
53109
type AnIndexedLens' i s a = AnIndexedLens i s s a a
54110

55-
-- | A prism.
56-
type Prism s t a b = forall p. Choice p => Optic p s t a b
57-
type Prism' s a = Prism s s a a
58-
59111
type APrism s t a b = Optic (Market a b) s t a b
60112
type APrism' s a = APrism s s a a
61113

62-
-- | A traversal.
63-
type Traversal s t a b = forall p. Wander p => Optic p s t a b
64-
type Traversal' s a = Traversal s s a a
65-
66114
-- | A grate (http://r6research.livejournal.com/28050.html)
67115
type Grate s t a b = forall p. Closed p => Optic p s t a b
68116
type Grate' s a = Grate s s a a

0 commit comments

Comments
 (0)