semi-iso-0.1.0.0: Control/Lens/Internal/SemiIso.hs
{- |
Module : Data.Lens.Internal.SemiIso
Description : Internals of a SemiIso.
Copyright : (c) Paweł Nowak
License : MIT
Maintainer : Paweł Nowak <pawel834@gmail.com>
Stability : experimental
-}
module Control.Lens.Internal.SemiIso where
import Control.Monad
import Data.Profunctor
-- | Type used internally to access 'SemiIso'.
--
-- Continues the naming tradition of @lens@.
data Barter s t a b = Barter (a -> Either String s) (t -> Either String b)
instance Profunctor (Barter s t) where
lmap f (Barter l r) = Barter (l . f) r
rmap f (Barter l r) = Barter l (fmap f . r)
instance Choice (Barter s t) where
left' (Barter as st) = Barter
(either as (\_ -> Left "partial iso failed")) (fmap Left . st)
right' (Barter as st) = Barter
(either (\_ -> Left "partial iso failed") as) (fmap Right . st)
-- | Provides a profunctor the ability to fail with an error message.
--
-- This class could use some laws. It is certainly a bit ad-hoc.
class Profunctor p => Failure p where
tie :: p a (Either String b) -> p a b
attach :: p a b -> p (Either String a) b
instance Failure (Barter s t) where
tie (Barter f g) = Barter f (join . g)
attach (Barter f g) = Barter (>>= f) g