on master help sign in
Add a bifoldr.
be10e53Paweł Nowak
Control/Lens/SemiIso.hs+26−1
@@ -53,13 +53,18 @@ module Control.Lens.SemiIso (
53 swapped,
53 swapped,
54 associated,
54 associated,
55 constant,
55 constant,
56− exact
56+ exact,
57+
58+ -- * Folds.
59+ bifoldr
57 ) where
60 ) where
58
61
59import Control.Lens.Internal.SemiIso
62import Control.Lens.Internal.SemiIso
60import Control.Lens.Iso
63import Control.Lens.Iso
64+import Control.Monad
61import Data.Functor.Identity
65import Data.Functor.Identity
62import Data.Traversable
66import Data.Traversable
67+import Data.Foldable
63
68
64-- | A semi-isomorphism is a partial isomorphism with weakened laws.
69-- | A semi-isomorphism is a partial isomorphism with weakened laws.
65--
70--
@@ -134,3 +139,23 @@ exact x = semiIso f g
134 f _ = Right x
139 f _ = Right x
135 g y | x == y = Right ()
140 g y | x == y = Right ()
136 | otherwise = Left "exact: not equal"
141 | otherwise = Left "exact: not equal"
142+
143+-- | Constructs a bidirectional fold.
144+--
145+-- \-> Right folds using the (->) part of the given semi-iso.
146+--
147+-- \<- Right unfolds using the (<-) part of the given semi-iso.
148+bifoldr :: ASemiIso (b, a) (Maybe (b, a)) a a -> SemiIso' (a, [b]) a
149+bifoldr ai = semiIso (f ai) (g ai)
150+ where
151+ f = uncurry . foldrM . curry . apply
152+ g = unfoldrM . unapply
153+
154+ unfoldrM :: Monad m => (a -> m (Maybe (b, a))) -> a -> m (a, [b])
155+ unfoldrM f a = do
156+ r <- f a
157+ case r of
158+ Just (b, new_a) -> do
159+ (final_a, bs) <- unfoldrM f new_a
160+ return (final_a, b : bs)
161+ Nothing -> return (a, [])
semi-iso.cabal+1−1
@@ -1,5 +1,5 @@
1name: semi-iso
1name: semi-iso
2−version: 0.2.0.0
2+version: 0.2.1.0
3synopsis: Weakened partial isomorphisms that work with lenses.
3synopsis: Weakened partial isomorphisms that work with lenses.
4description: Semi-isomorphisms are partial isomorphisms with weakened iso laws.
4description: Semi-isomorphisms are partial isomorphisms with weakened iso laws.
5 And they work with Iso and Prism from @lens@!
5 And they work with Iso and Prism from @lens@!