Skip to content

Commit 0d76a75

Browse files
committed
replicated, folded and ALens.
1 parent c111b3d commit 0d76a75

File tree

11 files changed

+158
-1
lines changed

11 files changed

+158
-1
lines changed

bower.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"purescript-const": "~0.5.0",
2222
"purescript-identity": "~0.4.0",
2323
"purescript-profunctor": "~0.3.0",
24-
"purescript-lists": "~0.7.0"
24+
"purescript-lists": "~0.7.0",
25+
"purescript-unsafe-coerce": "~0.1.0"
2526
}
2627
}

docs/Data/Lens/Fold.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,4 +86,20 @@ hasn't :: forall s t a b r. (BooleanAlgebra r) => Fold (Conj r) s t a b -> s ->
8686

8787
Determines whether a `Fold` does not have a focus.
8888

89+
#### `filtered`
90+
91+
``` purescript
92+
filtered :: forall p a. (Choice p) => (a -> Boolean) -> OpticP p a a
93+
```
94+
95+
Filters on a predicate.
96+
97+
#### `replicated`
98+
99+
``` purescript
100+
replicated :: forall r a b t f. (Applicative f, Contravariant f) => Int -> Optic (Star f) a b a t
101+
```
102+
103+
Replicates the elements of a fold.
104+
89105

docs/Data/Lens/Internal/Shop.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
## Module Data.Lens.Internal.Shop
2+
3+
This module defines the `Shop` profunctor
4+
5+
#### `Shop`
6+
7+
``` purescript
8+
data Shop a b s t
9+
= Shop (s -> a) (s -> b -> t)
10+
```
11+
12+
The `Shop` profunctor characterizes a `Lens`.
13+
14+
##### Instances
15+
``` purescript
16+
instance profunctorShop :: Profunctor (Shop a b)
17+
instance strongShop :: Strong (Shop a b)
18+
```
19+
20+

docs/Data/Lens/Internal/Void.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
## Module Data.Lens.Internal.Void
2+
3+
This module defines the empty `Void` type.
4+
5+
#### `Void`
6+
7+
``` purescript
8+
data Void
9+
```
10+
11+
#### `absurd`
12+
13+
``` purescript
14+
absurd :: forall a. Void -> a
15+
```
16+
17+
#### `coerce`
18+
19+
``` purescript
20+
coerce :: forall f a b. (Contravariant f, Functor f) => f a -> f b
21+
```
22+
23+

docs/Data/Lens/Lens.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,16 @@ lens :: forall s t a b. (s -> a) -> (s -> b -> t) -> Lens s t a b
1616

1717
Create a `Lens` from a getter/setter pair.
1818

19+
#### `withLens`
20+
21+
``` purescript
22+
withLens :: forall s t a b r. ALens s t a b -> ((s -> a) -> (s -> b -> t) -> r) -> r
23+
```
24+
25+
#### `cloneLens`
26+
27+
``` purescript
28+
cloneLens :: forall s t a b. ALens s t a b -> Lens s t a b
29+
```
30+
1931

docs/Data/Lens/Types.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,18 @@ A lens.
5656
type LensP s a = Lens s s a a
5757
```
5858

59+
#### `ALens`
60+
61+
``` purescript
62+
type ALens s t a b = Optic (Shop a b) s t a b
63+
```
64+
65+
#### `ALensP`
66+
67+
``` purescript
68+
type ALensP s a = ALens s s a a
69+
```
70+
5971
#### `Prism`
6072

6173
``` purescript

src/Data/Lens/Fold.purs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,29 @@
33
module Data.Lens.Fold
44
( (^?), (^..)
55
, preview, foldOf, foldMapOf, foldrOf, foldlOf, toListOf, has, hasn't
6+
, replicated, filtered
67
) where
78

89
import Prelude
910
import Data.Const
1011
import Data.Maybe
1112
import Data.List
13+
import Data.Either
14+
import Data.Monoid
1215
import Data.Maybe.First
1316
import Data.Monoid.Endo
1417
import Data.Monoid.Conj
1518
import Data.Monoid.Disj
1619
import Data.Monoid.Dual
20+
import Data.Functor.Contravariant
21+
import Data.Foldable
22+
import Data.Profunctor
1723
import Data.Profunctor.Star
24+
import Data.Profunctor.Choice
1825
import Data.Lens.Types
1926
import Data.Lens.Internal.Tagged
27+
import Data.Lens.Internal.Void
28+
import Control.Apply
2029

2130
infixl 8 ^?
2231
infixl 8 ^..
@@ -60,3 +69,21 @@ has p = runDisj <<< foldMapOf p (const (Disj top))
6069
-- | Determines whether a `Fold` does not have a focus.
6170
hasn't :: forall s t a b r. (BooleanAlgebra r) => Fold (Conj r) s t a b -> s -> r
6271
hasn't p = runConj <<< foldMapOf p (const (Conj bottom))
72+
73+
-- | Filters on a predicate.
74+
filtered :: forall p a. (Choice p) => (a -> Boolean) -> OpticP p a a
75+
filtered f = dimap (\x -> if f x then Right x else Left x) (either id id) <<< right
76+
77+
-- | Replicates the elements of a fold.
78+
replicated
79+
:: forall r a b t f. (Applicative f, Contravariant f)
80+
=> Int -> Optic (Star f) a b a t
81+
replicated n p = Star (flip go n <<< runStar p) where
82+
go x 0 = coerce (pure unit)
83+
go x n = x *> go x (n - 1)
84+
85+
-- | Folds over a `Foldable` container.
86+
folded
87+
:: forall f g a b t r. (Applicative f, Contravariant f, Foldable g)
88+
=> Optic (Star f) (g a) b a t
89+
folded p = Star $ foldr (\a r -> runStar p a *> r) (coerce $ pure unit)

src/Data/Lens/Internal/Shop.purs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
-- | This module defines the `Shop` profunctor
2+
3+
module Data.Lens.Internal.Shop where
4+
5+
import Prelude
6+
import Data.Tuple
7+
import Data.Profunctor
8+
import Data.Profunctor.Strong
9+
10+
-- | The `Shop` profunctor characterizes a `Lens`.
11+
data Shop a b s t = Shop (s -> a) (s -> b -> t)
12+
13+
instance profunctorShop :: Profunctor (Shop a b) where
14+
dimap f g (Shop x y) = Shop (x <<< f) (\s -> g <<< y (f s))
15+
16+
instance strongShop :: Strong (Shop a b) where
17+
first (Shop x y) = Shop (\(Tuple a _) -> x a) (\(Tuple s c) b -> Tuple (y s b) c)
18+
second (Shop x y) = Shop (\(Tuple _ a) -> x a) (\(Tuple c s) b -> Tuple c (y s b))

src/Data/Lens/Internal/Void.purs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
-- | This module defines the empty `Void` type.
2+
3+
module Data.Lens.Internal.Void where
4+
5+
import Prelude
6+
import Data.Functor.Contravariant
7+
import Unsafe.Coerce
8+
9+
data Void
10+
11+
absurd :: forall a. Void -> a
12+
absurd = unsafeCoerce
13+
14+
coerce :: forall f a b. (Contravariant f, Functor f) => f a -> f b
15+
coerce a = absurd <$> (absurd >$< a)

src/Data/Lens/Lens.purs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@
33
module Data.Lens.Lens
44
( lens
55
, lens'
6+
, withLens
7+
, cloneLens
68
) where
79

810
import Prelude
911

1012
import Data.Tuple
1113
import Data.Lens.Types
14+
import Data.Lens.Internal.Shop
1215
import Data.Profunctor
1316
import Data.Profunctor.Strong
1417

@@ -18,3 +21,9 @@ lens' to pab = dimap to (\(Tuple b f) -> f b) (first pab)
1821
-- | Create a `Lens` from a getter/setter pair.
1922
lens :: forall s t a b. (s -> a) -> (s -> b -> t) -> Lens s t a b
2023
lens get set = lens' \s -> Tuple (get s) \b -> set s b
24+
25+
withLens :: forall s t a b r. ALens s t a b -> ((s -> a) -> (s -> b -> t) -> r) -> r
26+
withLens l f = case l (Shop id \_ b -> b) of Shop x y -> f x y
27+
28+
cloneLens :: forall s t a b. ALens s t a b -> Lens s t a b
29+
cloneLens l = withLens l \x y p -> lens x y p

0 commit comments

Comments
 (0)