Copyright | (c) Justin Le 2017 |
---|---|
License | BSD3 |
Maintainer | justin@jle.im |
Stability | experimental |
Portability | non-portable |
Safe Haskell | None |
Language | Haskell2010 |
A poor substitute for the Control.Lens.Iso module in lens, providing
the Iso
type synonym and some sample useful Iso
s for usage with
backprop, without incuring a lens dependency.
If you also import lens, you should only use this module for the
Iso
s it exports, and not import the redefined Iso
type synonym or
from
/ iso
/ review
.
- type Iso s t a b = forall p f. (Profunctor p, Functor f) => p a (f b) -> p s (f t)
- type Iso' s a = Iso s s a a
- iso :: (s -> a) -> (b -> t) -> Iso s t a b
- from :: Iso' s a -> Iso' a s
- review :: Iso s t a b -> b -> t
- view :: Getting a s a -> s -> a
- coerced :: Coercible s a => Iso' s a
- gTuple :: (Generic a, Code a ~ '[as]) => Iso' a (Tuple as)
- gSOP :: Generic a => Iso' a (Sum Tuple (Code a))
- sum1 :: Iso' (Sum f '[a]) (f a)
- resum1 :: Iso' (f a) (Sum f '[a])
- data Prod k f a :: forall k. (k -> *) -> [k] -> * where
- type Tuple = Prod * I
- data Sum k f a :: forall k. (k -> *) -> [k] -> * where
- newtype I a :: * -> * = I {
- getI :: a
Isomorphisms
type Iso s t a b = forall p f. (Profunctor p, Functor f) => p a (f b) -> p s (f t) Source #
A family of isomorphisms. See Iso'
.
type Iso' s a = Iso s s a a Source #
An
encodes an isomorphism between an Iso'
s as
and an a
. It
basically lets you go from s -> a
and back (from a -> s
) while
preserving structure. You can basically imagine an
to be
an Iso'
s a(s -> a, a -> s)
tuple.
You can get the "forward" direction of an Iso'
with view
:
view
:: Iso'' s a -> (s -> a)
And the "backwards" direction with review
:
review
:: Iso'' s a -> (a -> s)
You can construct an Iso'
using iso
, giving the forward and
backwards functions:
>>>
myIso :: Iso' (Identity a) a
myIso = iso runIdentity Identity>>>
view myIso (Identity "hello")
"hello">>>
review myIso "hello"
Identity "hello"
One powerful thing about Iso'
s is that they're composable using .
:
(.
) ::Iso'
c b ->Iso'
b a ->Iso'
c a
This is basically provided here so that this package doesn't incurr a lens dependecy, but if you already depend on lens, you should use the version from Control.Lens.Iso instead.
Construction and usage
iso :: (s -> a) -> (b -> t) -> Iso s t a b Source #
Construct an Iso
by giving the "forward" and "backward" direction
functions:
>>>
myIso :: Iso' (Identity a) a
myIso = iso runIdentity Identity>>>
view myIso (Identity "hello")
"hello">>>
review myIso "hello"
Identity "hello"
This is basically provided here so that this package doesn't incurr a lens dependecy, but if you already depend on lens, you should use the version from Control.Lens.Iso instead.
from :: Iso' s a -> Iso' a s Source #
Reverse an Iso'
. The forward function becomes the backwards
function, and the backwards function becomes the forward function.
This is basically provided here so that this package doesn't incurr a lens dependecy, but if you already depend on lens, you should use the version from Control.Lens.Review instead.
review :: Iso s t a b -> b -> t Source #
Get the "reverse" direction function from an Iso
.
This is basically provided here so that this package doesn't incurr a lens dependecy, but if you already depend on lens, you should use the version from Control.Lens.Review instead.
view :: Getting a s a -> s -> a #
>>>
view _1 (1, 2)
1
The reason it's not in Lens.Micro is that view
in lens has a more general signature:
view :: MonadReader s m => Getting a s a -> m a
So, you would be able to use this view
with functions, but not in various reader monads. For most people this shouldn't be an issue; if it is for you, use view
from microlens-mtl.
Useful Isos
coerced :: Coercible s a => Iso' s a Source #
A useful Iso
between two types with the same runtime representation.
gTuple :: (Generic a, Code a ~ '[as]) => Iso' a (Tuple as) Source #
An Iso
between a type that is a product type, and a tuple that
contains all of its components. Uses Generics.SOP and the
Generic
typeclass.
>>>
import qualified Generics.SOP as SOP
>>>
data Foo = A Int Bool deriving Generic
>>>
instance SOP.Generic Foo
>>>
view gTuple (A 10 True)
10 ::< True ::< Ø>>>
review gTuple (15 ::< False ::< Ø)
A 15 False
gSOP :: Generic a => Iso' a (Sum Tuple (Code a)) Source #
An Iso
between a sum type whose constructors are products, and a sum
(Sum
) of products (Tuple
). Uses Generics.SOP and the
Generic
typeclass.
>>>
import qualified Generics.SOP as SOP
>>>
data Bar = A Int Bool | B String Double
>>>
instance SOP.Generic Bar
>>>
'view' 'gSOP' (A 10 True)
'InL' (10 ::< True ::< Ø)>>>
'view' 'gSOP' (B "hello" 3.4)
'InR' ('InL' ("hello" ::< 3.4 ::< Ø))>>>
'review' 'gTuple' ('InL' (15 ::< False ::< Ø))
A 15 False>>>
'review' 'gTuple' ('InR' ('InL' ("bye" ::< 9.8 ::< Ø)))
B "bye" 9.8
Utility types
See Numeric.Backprop for a mini-tutorial on Prod
and
Tuple
, and Numeric.Backprop for a mini-tutorial on Sum
.
data Prod k f a :: forall k. (k -> *) -> [k] -> * where #
Witness ØC ØC (Prod k f (Ø k)) | |
IxFunctor1 k [k] (Index k) (Prod k) | |
IxFoldable1 k [k] (Index k) (Prod k) | |
IxTraversable1 k [k] (Index k) (Prod k) | |
Functor1 [k] k (Prod k) | |
Foldable1 [k] k (Prod k) | |
Traversable1 [k] k (Prod k) | |
TestEquality k f => TestEquality [k] (Prod k f) | |
BoolEquality k f => BoolEquality [k] (Prod k f) | |
Eq1 k f => Eq1 [k] (Prod k f) | |
Ord1 k f => Ord1 [k] (Prod k f) | |
Show1 k f => Show1 [k] (Prod k f) | |
Read1 k f => Read1 [k] (Prod k f) | |
(Known [k] (Length k) as, Every k (Known k f) as) => Known [k] (Prod k f) as | |
(Witness p q (f a1), Witness s t (Prod a f as)) => Witness (p, s) (q, t) (Prod a f ((:<) a a1 as)) | |
ListC ((<$>) Constraint * Eq ((<$>) * k f as)) => Eq (Prod k f as) | |
(ListC ((<$>) Constraint * Eq ((<$>) * k f as)), ListC ((<$>) Constraint * Ord ((<$>) * k f as))) => Ord (Prod k f as) | |
ListC ((<$>) Constraint * Show ((<$>) * k f as)) => Show (Prod k f as) | |
type WitnessC ØC ØC (Prod k f (Ø k)) | |
type KnownC [k] (Prod k f) as | |
type WitnessC (p, s) (q, t) (Prod a f ((:<) a a1 as)) | |
data Sum k f a :: forall k. (k -> *) -> [k] -> * where #
Witness p q (f a) => Witness p q (Sum k f ((:) k a ([] k))) | |
(Witness p q (f a1), Witness p q (Sum a f ((:<) a b as))) => Witness p q (Sum a f ((:<) a a1 ((:<) a b as))) | |
IxFunctor1 k [k] (Index k) (Sum k) | |
IxFoldable1 k [k] (Index k) (Sum k) | |
IxTraversable1 k [k] (Index k) (Sum k) | |
Functor1 [k] k (Sum k) | |
Foldable1 [k] k (Sum k) | |
Traversable1 [k] k (Sum k) | |
Eq1 k f => Eq1 [k] (Sum k f) | |
Ord1 k f => Ord1 [k] (Sum k f) | |
Show1 k f => Show1 [k] (Sum k f) | |
Read1 k f => Read1 [k] (Sum k f) | |
ListC ((<$>) Constraint * Eq ((<$>) * k f as)) => Eq (Sum k f as) | |
(ListC ((<$>) Constraint * Eq ((<$>) * k f as)), ListC ((<$>) Constraint * Ord ((<$>) * k f as))) => Ord (Sum k f as) | |
ListC ((<$>) Constraint * Show ((<$>) * k f as)) => Show (Sum k f as) | |
type WitnessC p q (Sum a f ((:<) a a1 ((:<) a b as))) | |
type WitnessC p q (Sum k f ((:) k a ([] k))) | |