Skip to content
Open
22 changes: 20 additions & 2 deletions src/Data/Lens/Lens/Tuple.purs
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
module Data.Lens.Lens.Tuple
( _1
, _2
, _1M
, _2M
, module Data.Profunctor.Strong
) where

import Data.Lens.Lens (Lens)
import Prelude
import Data.Lens.Lens (Lens, lens)
import Data.Profunctor.Strong (first, second)
import Data.Tuple (Tuple)
import Data.Tuple (Tuple, fst, snd)
import Data.Tuple.Nested ((/\))

-- | Lens for the first component of a `Tuple`.
_1 :: forall a b c. Lens (Tuple a c) (Tuple b c) a b
Expand All @@ -15,3 +19,17 @@ _1 = first
-- | Lens for the second component of a `Tuple`.
_2 :: forall a b c. Lens (Tuple c a) (Tuple c b) a b
_2 = second

-- | Lens for the first component of a `Tuple` in a monadic context.
_1M :: forall a b c m. Monad m => Lens (Tuple a c) (m (Tuple b c)) a (m b)
_1M =
lens fst \(_ /\ b) ma -> do
a <- ma
pure $ a /\ b

-- | Lens for the second component of a `Tuple` in a monadic context.
_2M :: forall a b c m. Monad m => Lens (Tuple c a) (m (Tuple c b)) a (m b)
_2M =
lens snd \(a /\ _) mb -> do
b <- mb
pure $ a /\ b
13 changes: 11 additions & 2 deletions src/Data/Lens/Prism/Either.purs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ module Data.Lens.Prism.Either
, module Data.Profunctor.Choice
) where

import Data.Either (Either)
import Data.Lens.Prism (Prism)
import Prelude
import Data.Either (Either(..), either)
import Data.Lens.Prism (Prism, prism)
import Data.Profunctor.Choice (left, right)

-- | Prism for the `Left` constructor of `Either`.
Expand All @@ -15,3 +16,11 @@ _Left = left
-- | Prism for the `Right` constructor of `Either`.
_Right :: forall a b c. Prism (Either c a) (Either c b) a b
_Right = right

-- | Prism for the `Left` constructor of `Either` in a monadic context.
_LeftM :: forall a b c m. Monad m => Prism (Either a c) (m (Either b c)) a (m b)
_LeftM = prism (map Left) (either Right (Left <<< pure <<< Right))

-- | Prism for the `Right` constructor of `Either` in a monadic context.
_RightM :: forall a b c m. Monad m => Prism (Either c a) (m (Either c b)) a (m b)
_RightM = prism (map Right) (either (Left <<< pure <<< Left) Right)
10 changes: 8 additions & 2 deletions src/Data/Lens/Prism/Maybe.purs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
module Data.Lens.Prism.Maybe where

import Prelude

import Data.Either (Either(..))
import Data.Maybe (Maybe(..), maybe)

import Data.Lens.Prism (Prism, prism)

-- | Prism for the `Nothing` constructor of `Maybe`.
Expand All @@ -14,3 +12,11 @@ _Nothing = prism (const Nothing) $ maybe (Right unit) (const $ Left Nothing)
-- | Prism for the `Just` constructor of `Maybe`.
_Just :: forall a b. Prism (Maybe a) (Maybe b) a b
_Just = prism Just $ maybe (Left Nothing) Right

-- | Prism for the `Nothing` constructor of `Maybe` in a monadic context.
_NothingM :: forall a b m. Monad m => Prism (Maybe a) (m (Maybe b)) Unit (m Unit)
_NothingM = prism (const $ pure Nothing) (maybe (Right unit) (const $ Left $ pure Nothing))

-- | Prism for the `Just` constructor of `Maybe` in a monadic context.
_JustM :: forall a b m. Monad m => Prism (Maybe a) (m (Maybe b)) a (m b)
_JustM = prism (map Just) (maybe (Left $ pure Nothing) Right)
79 changes: 39 additions & 40 deletions src/Data/Lens/Traversal.purs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
-- | ```
-- |
-- | Many of the functions you'll use are documented in `Data.Lens.Fold`.

module Data.Lens.Traversal
( traversed
, element
Expand All @@ -30,7 +29,6 @@ module Data.Lens.Traversal
) where

import Prelude

import Control.Alternative (class Alternative)
import Control.Plus (empty)
import Data.Lens.Indexed (iwander, positions, unIndex)
Expand All @@ -53,8 +51,8 @@ traversed :: forall t a b. Traversable t => Traversal (t a) (t b) a b
traversed = wander traverse

-- | Turn a pure profunctor `Traversal` into a `lens`-like `Traversal`.
traverseOf
:: forall f s t a b . Optic (Star f) s t a b -> (a -> f b) -> s -> f t
traverseOf ::
forall f s t a b. Optic (Star f) s t a b -> (a -> f b) -> s -> f t
traverseOf = under Star

-- | Sequence the foci of an optic, pulling out an "effect".
Expand All @@ -81,21 +79,21 @@ traverseOf = under Star
-- | [0.15556037108154985,0.28500369615270515]
-- | unit
-- | ```
sequenceOf
:: forall f s t a . Optic (Star f) s t (f a) a -> s -> f t
sequenceOf ::
forall f s t a. Optic (Star f) s t (f a) a -> s -> f t
sequenceOf t = traverseOf t identity

-- | Tries to map over a `Traversal`; returns `empty` if the traversal did
-- | not have any new focus.
failover
:: forall f s t a b
. Alternative f
=> Optic (Star (Tuple (Disj Boolean))) s t a b
-> (a -> b)
-> s
-> f t
failover ::
forall f s t a b.
Alternative f =>
Optic (Star (Tuple (Disj Boolean))) s t a b ->
(a -> b) ->
s ->
f t
failover t f s = case unwrap (t $ Star $ Tuple (Disj true) <<< f) s of
Tuple (Disj true) x -> pure x
Tuple (Disj true) x -> pure x
Tuple (Disj false) _ -> empty

-- | Combine an index and a traversal to narrow the focus to a single
Expand All @@ -108,40 +106,41 @@ failover t f s = case unwrap (t $ Star $ Tuple (Disj true) <<< f) s of
-- | The resulting traversal is called an *affine traversal*, which
-- | means that the traversal focuses on one or zero (if the index is out of range)
-- | results.
element
:: forall p s t a
. Wander p
=> Int
-> Traversal s t a a
-> Optic p s t a a
element ::
forall p s t a.
Wander p =>
Int ->
Traversal s t a a ->
Optic p s t a a
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you mind preserving the existing formatting? That'll just help this PR stay easy to review and if we switch to arrow-last style we can apply it in one commit across the repository.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, is there a vs code setting that can bring that formatting in? Apologies for the clutter!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the formatting back now 👍
I also marked it ready for review.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We haven’t formally adopted a formatter, so in these libraries it’s mostly about following the existing formatting until we do adopt one. Thanks!

element n tr = unIndex $ elementsOf (positions tr) (_ == n)

-- | Traverse elements of an `IndexedTraversal` whose index satisfy a predicate.
elementsOf
:: forall p i s t a
. Wander p
=> IndexedTraversal i s t a a
-> (i -> Boolean)
-> IndexedOptic p i s t a a
elementsOf tr pr = iwander \f ->
unwrap $ tr $ Indexed $ Star $ \(Tuple i a) -> if pr i then f i a else pure a
elementsOf ::
forall p i s t a.
Wander p =>
IndexedTraversal i s t a a ->
(i -> Boolean) ->
IndexedOptic p i s t a a
elementsOf tr pr =
iwander \f ->
unwrap $ tr $ Indexed $ Star $ \(Tuple i a) -> if pr i then f i a else pure a

-- | Turn a pure profunctor `IndexedTraversal` into a `lens`-like `IndexedTraversal`.
itraverseOf
:: forall f i s t a b
. IndexedOptic (Star f) i s t a b
-> (i -> a -> f b)
-> s
-> f t
itraverseOf ::
forall f i s t a b.
IndexedOptic (Star f) i s t a b ->
(i -> a -> f b) ->
s ->
f t
itraverseOf t = under Star (t <<< Indexed) <<< uncurry

-- | Flipped version of `itraverseOf`.
iforOf
:: forall f i s t a b
. IndexedOptic (Star f) i s t a b
-> s
-> (i -> a -> f b)
-> f t
iforOf ::
forall f i s t a b.
IndexedOptic (Star f) i s t a b ->
s ->
(i -> a -> f b) ->
f t
iforOf = flip <<< itraverseOf

cloneTraversal :: forall s t a b. ATraversal s t a b -> Traversal s t a b
Expand Down