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 a`s`

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 runIdentity Identity`myIso :: Iso' (Identity a) a`

`>>>`

"hello"`view myIso (Identity "hello")`

`>>>`

Identity "hello"`review myIso "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 runIdentity Identity`myIso :: Iso' (Identity a) a`

`>>>`

"hello"`view myIso (Identity "hello")`

`>>>`

Identity "hello"`review myIso "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 #

`>>>`

1`view _1 (1, 2)`

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`

`>>>`

10 ::< True ::< Ø`view gTuple (A 10 True)`

`>>>`

A 15 False`review gTuple (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`

`>>>`

'InL' (10 ::< True ::< Ø)`'view' 'gSOP' (A 10 True)`

`>>>`

'InR' ('InL' ("hello" ::< 3.4 ::< Ø))`'view' 'gSOP' (B "hello" 3.4)`

`>>>`

A 15 False`'review' 'gTuple' ('InL' (15 ::< False ::< Ø))`

`>>>`

B "bye" 9.8`'review' 'gTuple' ('InR' ('InL' ("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))) | |