-
Notifications
You must be signed in to change notification settings - Fork 40
Linear lens combinators #195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,24 +23,27 @@ module Control.Optics.Linear.Internal | |
| , _Just, _Nothing | ||
| , traversed | ||
| -- * Using optics | ||
| , get, set, gets | ||
| , get, set, gets, setSwap | ||
| , match, build | ||
| , over, over' | ||
| , traverseOf, traverseOf' | ||
| , lengthOf | ||
| , withIso, withPrism | ||
| , toListOf, lengthOf | ||
| , withIso, withLens, withPrism | ||
| -- * Constructing optics | ||
| , iso, prism | ||
| , iso, lens, prism | ||
| ) | ||
| where | ||
|
|
||
| import qualified Control.Arrow as NonLinear | ||
| import qualified Data.Bifunctor.Linear as Bifunctor | ||
| import Data.Bifunctor.Linear (SymmetricMonoidal) | ||
| import Data.Profunctor.Linear | ||
| import Data.Functor.Compose hiding (getCompose) | ||
| import Data.Functor.Linear | ||
| import qualified Data.Profunctor.Kleisli.Linear as Linear | ||
| import Data.Void | ||
| import GHC.Exts (FUN) | ||
| import GHC.Types | ||
| import Prelude.Linear | ||
| import qualified Prelude as P | ||
|
|
||
|
|
@@ -67,6 +70,10 @@ assoc = iso Bifunctor.lassoc Bifunctor.rassoc | |
| (.>) :: Optic_ arr a b s t -> Optic_ arr x y a b -> Optic_ arr x y s t | ||
| Optical f .> Optical g = Optical (f P.. g) | ||
|
|
||
|
|
||
| lens :: (s #-> (a, b #-> t)) -> Lens a b s t | ||
| lens k = Optical $ \f -> dimap k (\(x,g) -> g $ x) (first f) | ||
|
|
||
| prism :: (b #-> t) -> (s #-> Either t a) -> Prism a b s t | ||
| prism b s = Optical $ \f -> dimap s (either id id) (second (rmap b f)) | ||
|
|
||
|
|
@@ -97,6 +104,9 @@ over (Optical l) f = getLA (l (LA f)) | |
| traverseOf :: Optic_ (Linear.Kleisli f) a b s t -> (a #-> f b) -> s #-> f t | ||
| traverseOf (Optical l) f = Linear.runKleisli (l (Linear.Kleisli f)) | ||
|
|
||
| toListOf :: Optic_ (NonLinear.Kleisli (Const [a])) a b s t -> s -> [a] | ||
| toListOf l = gets l (\a -> [a]) | ||
|
|
||
| get :: Optic_ (NonLinear.Kleisli (Const a)) a b s t -> s -> a | ||
| get l = gets l P.id | ||
|
|
||
|
|
@@ -106,6 +116,9 @@ gets (Optical l) f s = getConst' (NonLinear.runKleisli (l (NonLinear.Kleisli (Co | |
| set :: Optic_ (->) a b s t -> b -> s -> t | ||
| set (Optical l) x = l (const x) | ||
|
|
||
| setSwap :: Optic_ (Linear.Kleisli (Compose (LinearArrow b) ((,) a))) a b s t -> s #-> b #-> (a, t) | ||
| setSwap (Optical l) s = getLA (getCompose (Linear.runKleisli (l (Linear.Kleisli (\a -> Compose (LA (\b -> (a,b)))))) s)) | ||
|
|
||
| match :: Optic_ (Market a b) a b s t -> s #-> Either t a | ||
| match (Optical l) = snd (runMarket (l (Market id Right))) | ||
|
|
||
|
|
@@ -139,3 +152,10 @@ withIso (Optical l) f = f fro to | |
| withPrism :: Optic_ (Market a b) a b s t -> ((b #-> t) -> (s #-> Either t a) -> r) -> r | ||
| withPrism (Optical l) f = f b m | ||
| where Market b m = l (Market id Right) | ||
|
|
||
| withLens :: Optic_ (Linear.Kleisli (Compose ((,) a) (FUN 'One b))) a b s t -> s #-> (a, b #-> t) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Given that this is just migration and that I'm going to take a pass through optics, this, although complicated, is fine right now. When I take a pass I'm going to comment that One question: could we change
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The better term is inverse
It would not work. |
||
| withLens (Optical l) s = getCompose (Linear.runKleisli (l (Linear.Kleisli (\a -> Compose (a, id)))) s) | ||
|
|
||
| -- linear variant of getCompose | ||
| getCompose :: Compose f g a #-> f (g a) | ||
| getCompose (Compose x) = x | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,7 @@ module Data.Functor.Linear.Internal where | |
|
|
||
| import Prelude.Linear.Internal | ||
| import Prelude (Maybe(..), Either(..)) | ||
| import Data.Functor.Compose | ||
| import Data.Functor.Const | ||
| import Data.Monoid.Linear | ||
| import Data.Functor.Identity | ||
|
|
@@ -97,6 +98,14 @@ instance Applicative Identity where | |
| pure = Identity | ||
| Identity f <*> Identity x = Identity (f x) | ||
|
|
||
| instance (Functor f, Functor g) => Functor (Compose f g) where | ||
| fmap f (Compose x) = Compose (fmap (fmap f) x) | ||
|
|
||
| instance (Applicative f, Applicative g) => Applicative (Compose f g) where | ||
| pure x = Compose (pure (pure x)) | ||
| (Compose f) <*> (Compose x) = Compose (liftA2 (<*>) f x) | ||
| liftA2 f (Compose x) (Compose y) = Compose (liftA2 (liftA2 f) x y) | ||
|
|
||
|
Comment on lines
+101
to
+108
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like these. I needed them for |
||
| --------------------------------- | ||
| -- Monad transformer instances -- | ||
| --------------------------------- | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice; me likey 😏