11-- | This module defines functions for working with lenses.
22
3- module Data.Lens.Prism where
3+ module Data.Lens.Prism
4+ ( prism , prism' , review , nearly , only , clonePrism , withPrism , matching
5+ , is , isn't
6+ ) where
47
58import Prelude
69
@@ -11,17 +14,42 @@ import Data.Maybe
1114import Data.Maybe.First
1215import Data.Lens.Types
1316import Data.Lens.Internal.Tagged
17+ import Data.Lens.Internal.Market
18+ import Control.MonadPlus
1419import Data.Profunctor (dimap , rmap )
15- import Data.Profunctor.Choice ( left )
20+ import Data.Profunctor.Choice
1621
1722-- | Create a `Prism` from a constructor/pattern pair.
18- prism :: forall s t a b . (b -> t ) -> (s -> Either a t ) -> Prism s t a b
19- prism to fro pab = dimap fro (either id id) (left (rmap to pab))
23+ prism :: forall s t a b . (b -> t ) -> (s -> Either t a ) -> Prism s t a b
24+ prism to fro pab = dimap fro (either id id) (right (rmap to pab))
25+
26+ prism' :: forall s a . (a -> s ) -> (s -> Maybe a ) -> PrismP s a
27+ prism' to fro = prism to (\s -> maybe (Left s) Right (fro s))
2028
2129-- | Review a value through a `Prism`.
22- review :: forall s t a b . Prism s t a b -> b -> t
30+ review :: forall s t a b . Review s t a b -> b -> t
2331review p = unTagged <<< p <<< Tagged
2432
25- -- | Previews the value of a `Prism`, if there is any.
26- preview :: forall s t a b . Prism s t a b -> s -> Maybe a
27- preview p = runFirst <<< getConst <<< runStar (p (Star (Const <<< pure)))
33+ nearly :: forall a . a -> (a -> Boolean ) -> PrismP a Unit
34+ nearly x f = prism' (const x) (guard <<< f)
35+
36+ only :: forall a . (Eq a ) => a -> Prism a a Unit Unit
37+ only x = nearly x (== x)
38+
39+ clonePrism :: forall s t a b . APrism s t a b -> Prism s t a b
40+ clonePrism l = withPrism l go where
41+ -- the type checker doesn't like `prism` for `go`...
42+ go to fro pab = dimap fro (either id id) (right (rmap to pab))
43+
44+ withPrism :: forall s t a b r . APrism s t a b -> ((b -> t ) -> (s -> Either t a ) -> r ) -> r
45+ withPrism l f = case l (Market id Right ) of
46+ Market g h -> f g h
47+
48+ matching :: forall s t a b . APrism s t a b -> s -> Either t a
49+ matching l = withPrism l \_ f -> f
50+
51+ is :: forall s t a b r . (BooleanAlgebra r ) => APrism s t a b -> s -> r
52+ is l = either (const bottom) (const top) <<< matching l
53+
54+ isn't :: forall s t a b r . (BooleanAlgebra r ) => APrism s t a b -> s -> r
55+ isn't l = not <<< is l
0 commit comments