Copyright | (c) Paweł Nowak |
---|---|
License | MIT |
Maintainer | Paweł Nowak <pawel834@gmail.com> |
Stability | experimental |
Safe Haskell | Safe-Inferred |
Language | Haskell2010 |
Semi-isomorphisms were motivated by reversible parsing/pretty printing. For example we can map a number 12 to a string "12" (and the other way around). But the isomorphism is partial - we cannot map the string "forty-two" to a number.
Another example: when parsing a list of numbers like "12_53___42" we want to skip underscores
between numbers (and forget about them). During pretty printing we have to decide how many
underscores should we insert between numbers. Let's say we insert a single underscore. But now
prettyPrint (parse "12_53___42") = "12_53_42"
and not "12_53___42". We have to weaken
isomorphism laws to allow such semi-iso. Notice that
parse (prettyPrint (parse "12_53___42")) = parse "12_53___42" prettyPrint (parse (prettyPrint [12, 53, 42])) = prettyPrint [12, 53, 42]
Our semi-isomorphisms will obey weakened laws:
apply i >=> unapply i >=> apply i = apply i unapply i >=> apply i >=> unapply i = unapply i
When you see an "Either String a", the String is usually an error message.
Disclaimer: the name "semi-isomorphism" is fictitious and made up for this library. Any resemblance to known mathematical objects of the same name is purely coincidental.
- type SemiIso s t a b = forall p f. (Failure p, Traversable f) => p a (f b) -> p s (f t)
- type SemiIso' s a = SemiIso s s a a
- type ASemiIso s t a b = Barter a b a (Identity b) -> Barter a b s (Identity t)
- type ASemiIso' s a = ASemiIso s s a a
- semiIso :: (s -> Either String a) -> (b -> Either String t) -> SemiIso s t a b
- withSemiIso :: ASemiIso s t a b -> ((s -> Either String a) -> (b -> Either String t) -> r) -> r
- fromSemi :: ASemiIso s t a b -> SemiIso b a t s
- apply :: ASemiIso s t a b -> s -> Either String a
- unapply :: ASemiIso s t a b -> b -> Either String t
- unit :: Iso' a (a, ())
- swapped :: Swapped p => forall a b c d p f. (Profunctor p, Functor f) => p (p b a) (f (p d c)) -> p (p a b) (f (p c d))
- associated :: Iso' (a, (b, c)) ((a, b), c)
- constant :: a -> SemiIso' () a
- exact :: Eq a => a -> SemiIso' () a
Semi-isomorphism types.
type SemiIso s t a b = forall p f. (Failure p, Traversable f) => p a (f b) -> p s (f t) Source
A semi-isomorphism is a partial isomorphism with weakened laws.
Should satisfy laws:
apply i >=> unapply i >=> apply i = apply i unapply i >=> apply i >=> unapply i = unapply i
Every Prism
is a SemiIso
.
Every Iso
is a Prism
.
type ASemiIso s t a b = Barter a b a (Identity b) -> Barter a b s (Identity t) Source
When you see this as an argument to a function, it expects a SemiIso
.
type ASemiIso' s a = ASemiIso s s a a Source
When you see this as an argument to a function, it expects a SemiIso'
.
Constructing semi-isos.
semiIso :: (s -> Either String a) -> (b -> Either String t) -> SemiIso s t a b Source
Constructs a semi isomorphism from a pair of functions that can fail with an error message.
Consuming semi-isos.
withSemiIso :: ASemiIso s t a b -> ((s -> Either String a) -> (b -> Either String t) -> r) -> r Source
Extracts the two functions that characterize the SemiIso
.
unapply :: ASemiIso s t a b -> b -> Either String t Source
Applies the SemiIso
in the opposite direction.
Common semi-isomorphisms and isomorphisms.
swapped :: Swapped p => forall a b c d p f. (Profunctor p, Functor f) => p (p b a) (f (p d c)) -> p (p a b) (f (p c d))
associated :: Iso' (a, (b, c)) ((a, b), c) Source
Products are associative.