-
Notifications
You must be signed in to change notification settings - Fork 6
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
Draft optics implementation #13
Closed
Closed
Changes from all commits
Commits
Show all changes
31 commits
Select commit
Hold shift + click to select a range
18c5e64
Typo
AriFordsham 66a7a95
Initial lenses
AriFordsham faa00e6
Initial optics
AriFordsham bccf8f8
PChoice
AriFordsham 15a03d5
Pair and Either optics lenses with new Profunctor and Lens hierarchy
AriFordsham 617d645
Runner for Optional
AriFordsham bf6b34b
Traversal attempt
AriFordsham 8da1769
Fixed instances
AriFordsham fe87fd6
Explicit CPSs - typing problem
AriFordsham db1ce86
continuation-based optics
AriFordsham 40da02f
Fix
AriFordsham 26997df
Cleanup
AriFordsham 855aeaa
Current progress
AriFordsham d88799e
Merge branch 'master' into ari/optics
AriFordsham a0ad1a3
Traversals with List
AriFordsham 605ea8a
Formatting
AriFordsham 9fb654e
Merge branch 'master' into ari/optics
AriFordsham b4e64f5
Updates
AriFordsham 80556fe
PList traversal
AriFordsham 85c16dc
Prototype Haskell Fix Traversal combinator
AriFordsham 1dacc89
Fix transcribed to Plutarch
AriFordsham 26d80c8
Merge branch 'master' into ari/optics
AriFordsham 39b3667
Current progress
AriFordsham 987abc0
Merge branch 'ari/simplified-generics' into ari/optics
AriFordsham 2d4a2ff
Merge branch 'ari/simplified-generics' into ari/optics
AriFordsham 0b876d6
Current progress
AriFordsham 39845aa
Merge branch 'ari/simplified-generics' into ari/optics
AriFordsham 8719e13
Current progress
AriFordsham 3589196
Merge branch 'ari/simplified-generics' into ari/optics
AriFordsham 32877e5
Implemented `pconstrained`
AriFordsham 050479a
Completed `traverse`
AriFordsham File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
/dist-newstyle | ||
cabal.project.local |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{-# LANGUAGE FlexibleInstances #-} | ||
|
||
module Plutarch.CPS.Optics.Iso where | ||
|
||
import Plutarch.CPS.Optics.Optic | ||
import Plutarch.CPS.Profunctor | ||
|
||
type CIso r s t a b = forall p. (IsCIso r p) => COptic r p s t a b | ||
|
||
type CIso' r s a = CIso r s s a a | ||
|
||
class (CProfunctor r p) => IsCIso r p | ||
|
||
instance IsCIso r (->) | ||
instance (Functor f) => IsCIso r (CStar r f) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
{-# LANGUAGE FlexibleInstances #-} | ||
|
||
module Plutarch.CPS.Optics.Lens where | ||
|
||
import Control.Monad | ||
import Control.Monad.Trans.Cont | ||
import Plutarch.CPS.Optics.Iso | ||
import Plutarch.CPS.Optics.Optic | ||
import Plutarch.CPS.Profunctor | ||
|
||
type CLens r s t a b = forall p. (IsCLens r p) => COptic r p s t a b | ||
|
||
type CLens' r s a = CLens r s s a a | ||
|
||
class (IsCIso r p, CStrong r p) => IsCLens r p | ||
|
||
instance (Functor f) => IsCLens r (CStar r f) | ||
|
||
clens :: (s -> Cont r a) -> (s -> b -> Cont r t) -> CLens r s t a b | ||
clens get set = cdimap (\s -> (s,) <$> get s) (uncurry set) . csecond' | ||
|
||
withCLens :: CLens r s t a b -> ((s -> Cont r a) -> (s -> b -> Cont r t) -> r') -> r' | ||
withCLens o f = f (clensGet l) (clensSet l) | ||
where | ||
l = o $ ConcreteLens {clensGet = return, clensSet = const return} | ||
|
||
data ConcreteLens r a b s t = ConcreteLens | ||
{ clensGet :: s -> Cont r a | ||
, clensSet :: s -> b -> t | ||
} | ||
|
||
instance CProfunctor r (ConcreteLens r a b) where | ||
cdimap ab cd l = | ||
ConcreteLens | ||
{ clensGet = ab >=> clensGet l | ||
, clensSet = \a b -> ab a >>= \b' -> clensSet l b' b >>= cd | ||
} | ||
|
||
instance CStrong r (ConcreteLens r a b) where | ||
cfirst' l = | ||
ConcreteLens | ||
{ clensGet = clensGet l . fst | ||
, clensSet = \(a, c) b -> (,c) <$> clensSet l a b | ||
} | ||
|
||
instance IsCIso r (ConcreteLens r a b) | ||
instance IsCLens r (ConcreteLens r a b) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
module Plutarch.CPS.Optics.Optic where | ||
|
||
import Control.Monad.Trans.Cont | ||
|
||
type COptic r p s t a b = p a (Cont r b) -> p s (Cont r t) | ||
|
||
type COptic' r p s a = COptic r p s s a a |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
{-# LANGUAGE FlexibleInstances #-} | ||
|
||
module Plutarch.CPS.Optics.Optional where | ||
|
||
import Plutarch.CPS.Optics.Lens | ||
import Plutarch.CPS.Optics.Optic | ||
import Plutarch.CPS.Optics.Prism | ||
|
||
import Control.Arrow | ||
import Control.Monad | ||
|
||
import Control.Monad.Trans.Cont | ||
import Plutarch.CPS.Optics.Iso | ||
import Plutarch.CPS.Profunctor | ||
|
||
type COptional r s t a b = forall p. (IsCOptional r p) => COptic r p s t a b | ||
|
||
type COptional' r s a = COptional r s s a a | ||
|
||
class (IsCLens r p, IsCPrism r p) => IsCOptional r p | ||
|
||
instance (Applicative f) => IsCOptional r (CStar r f) | ||
|
||
withCOptional :: COptional r s t a b -> ((s -> Cont r (Either t a)) -> (s -> b -> Cont r t) -> r') -> r' | ||
withCOptional o f = f (coptionalGet l >=> either (fmap Left) (return . Right)) (coptionalSet l) | ||
where | ||
l = o $ ConcreteOptional {coptionalGet = return . Right, coptionalSet = const return} | ||
|
||
data ConcreteOptional r a b s t = ConcreteOptional | ||
{ coptionalGet :: s -> Cont r (Either t a) | ||
, coptionalSet :: s -> b -> t | ||
} | ||
|
||
instance CProfunctor r (ConcreteOptional r a b) where | ||
cdimap ab cd o = | ||
ConcreteOptional | ||
{ coptionalGet = | ||
ab >=> coptionalGet o >=> return . left (>>= cd) | ||
, coptionalSet = \a b -> ab a >>= \b' -> coptionalSet o b' b >>= cd | ||
} | ||
|
||
instance CStrong r (ConcreteOptional r a b) where | ||
cfirst' o = | ||
ConcreteOptional | ||
{ coptionalGet = \(a, c) -> left (fmap (,c)) <$> coptionalGet o a | ||
, coptionalSet = \(a, c) b -> (,c) <$> coptionalSet o a b | ||
} | ||
|
||
csecond' o = | ||
ConcreteOptional | ||
{ coptionalGet = \(c, a) -> left (fmap (c,)) <$> coptionalGet o a | ||
, coptionalSet = \(c, a) b -> (c,) <$> coptionalSet o a b | ||
} | ||
|
||
instance CChoice r (ConcreteOptional r a b) where | ||
cleft' o = | ||
ConcreteOptional | ||
{ coptionalGet = | ||
either | ||
( coptionalGet o | ||
>=> return . left (fmap Left) | ||
) | ||
(return . Left . return . Right) | ||
, coptionalSet = | ||
\e b -> either (\a -> Left <$> coptionalSet o a b) (return . Right) e | ||
} | ||
|
||
cright' o = | ||
ConcreteOptional | ||
{ coptionalGet = | ||
either | ||
(return . Left . return . Left) | ||
( coptionalGet o | ||
>=> return . left (fmap Right) | ||
) | ||
, coptionalSet = | ||
\e b -> either (return . Left) (\a -> Right <$> coptionalSet o a b) e | ||
} | ||
|
||
instance IsCIso r (ConcreteOptional r a b) | ||
instance IsCLens r (ConcreteOptional r a b) | ||
instance IsCPrism r (ConcreteOptional r a b) | ||
instance IsCOptional r (ConcreteOptional r a b) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
{-# LANGUAGE FlexibleInstances #-} | ||
|
||
module Plutarch.CPS.Optics.Prism where | ||
|
||
import Control.Monad | ||
import Control.Monad.Trans.Cont | ||
import Plutarch.CPS.Optics.Iso | ||
import Plutarch.CPS.Optics.Optic | ||
import Plutarch.CPS.Profunctor | ||
|
||
type CPrism r s t a b = forall p. IsCPrism r p => COptic r p s t a b | ||
|
||
type CPrism' r a b = CPrism r a a b b | ||
|
||
class (IsCIso r p, CChoice r p) => IsCPrism r p | ||
|
||
instance (Applicative f) => IsCPrism r (CStar r f) | ||
|
||
cprism :: (b -> Cont r t) -> (s -> Cont r (Either t a)) -> CPrism r s t a b | ||
cprism inj prj = cdimap prj (either return inj) . cright' | ||
|
||
cprism' :: (b -> Cont r s) -> (s -> Cont r (Maybe a)) -> CPrism r s s a b | ||
cprism' inj prj = cprism inj (\s -> prj s >>= maybe (return $ Left s) (return . Right)) | ||
|
||
withCPrism :: | ||
CPrism r s t a b -> | ||
((b -> Cont r t) -> (s -> Cont r (Either t a)) -> r') -> | ||
r' | ||
withCPrism o f = | ||
f (cprismSet l) (cprismGet l >=> either (fmap Left) (return . Right)) | ||
where | ||
l = o $ ConcretePrism {cprismSet = return, cprismGet = return . Right} | ||
|
||
data ConcretePrism r a b s t = ConcretePrism | ||
{ cprismGet :: s -> Cont r (Either t a) | ||
, cprismSet :: b -> t | ||
} | ||
|
||
instance CProfunctor r (ConcretePrism r a b) where | ||
cdimap ab cd p = | ||
ConcretePrism | ||
{ cprismGet = | ||
ab | ||
>=> cprismGet p | ||
>=> either | ||
(\c -> Left . return <$> (c >>= cd)) | ||
(return . Right) | ||
, cprismSet = cprismSet p >=> cd | ||
} | ||
|
||
instance CChoice r (ConcretePrism r a b) where | ||
cleft' p = | ||
ConcretePrism | ||
{ cprismGet = | ||
either | ||
(cprismGet p >=> either (fmap (Left . return . Left)) (return . Right)) | ||
(return . Left . return . Right) | ||
, cprismSet = fmap Left . cprismSet p | ||
} | ||
|
||
instance IsCIso r (ConcretePrism r a b) | ||
instance IsCPrism r (ConcretePrism r a b) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
{-# LANGUAGE FlexibleInstances #-} | ||
|
||
module Plutarch.CPS.Optics.Traversal( | ||
CTraversal, | ||
CTraversal', | ||
ctraverse, | ||
ctraverseOf, | ||
ctraversal, | ||
) where | ||
|
||
import Control.Monad.Trans.Cont | ||
import Plutarch.CPS.Optics.Optic | ||
import Plutarch.CPS.Optics.Optional | ||
import Plutarch.CPS.Profunctor | ||
|
||
type CTraversal r s t a b = forall p. (IsCTraversal r p) => COptic r p s t a b | ||
|
||
type CTraversal' r s a = CTraversal r s s a a | ||
|
||
class (IsCOptional r p, CMonoidal r p) => IsCTraversal r p | ||
|
||
instance (Applicative f) => IsCTraversal r (CStar r f) | ||
|
||
ctraverse :: (CChoice r p, CMonoidal r p) => p a (Cont r b) -> p (FunList a c t) (Cont r (FunList b c t)) | ||
ctraverse k = cdimap (return . unFunList) (return . FunList) . cright' $ cpar k (ctraverse k) | ||
|
||
ctraverseOf :: | ||
(Applicative f) => | ||
CTraversal r s t a b -> | ||
(a -> Cont r (f b)) -> | ||
s -> | ||
Cont r (f (Cont r t)) | ||
ctraverseOf p = runCStar . p . CStar . (fmap . fmap . fmap) return | ||
|
||
newtype FunList a b t = FunList {unFunList :: Either t (a, FunList a b (b -> t))} | ||
|
||
single :: a -> FunList a b b | ||
single a = FunList $ Right (a, FunList $ Left id) | ||
|
||
instance Functor (FunList a b) where | ||
fmap f (FunList (Left t)) = FunList (Left (f t)) | ||
fmap f (FunList (Right (a, as))) = FunList (Right (a, fmap (f .) as)) | ||
|
||
instance Applicative (FunList a b) where | ||
pure = FunList . Left | ||
FunList (Left f) <*> l' = fmap f l' | ||
FunList (Right (a, l)) <*> l' = FunList (Right (a, fmap flip l <*> l')) | ||
|
||
fuse :: FunList b b t -> Cont r t | ||
fuse = either return (\(a, c) -> ($ a) <$> fuse c) . unFunList | ||
|
||
ctraversal :: | ||
(forall f. Applicative f => (a -> f b) -> (s -> Cont r (f t))) -> | ||
CTraversal r s t a b | ||
ctraversal h = cdimap (h single) fuse . ctraverse |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
{-# LANGUAGE FlexibleInstances #-} | ||
|
||
module Plutarch.CPS.Profunctor where | ||
|
||
import Control.Applicative | ||
import Control.Monad | ||
import Control.Monad.Trans.Cont | ||
import Data.Tuple | ||
|
||
newtype CStar r f a b = CStar {runCStar :: a -> Cont r (f b)} | ||
|
||
class CProfunctor r p where | ||
cdimap :: (a -> Cont r b) -> (c -> Cont r d) -> p b (Cont r c) -> p a (Cont r d) | ||
|
||
clmap :: (CProfunctor r p) => (a -> Cont r b) -> p b (Cont r c) -> p a (Cont r c) | ||
clmap f = cdimap f return | ||
|
||
crmap :: (CProfunctor r p) => (b -> Cont r c) -> p a (Cont r b) -> p a (Cont r c) | ||
crmap = cdimap return | ||
|
||
instance CProfunctor r (->) where | ||
cdimap ab cd bc = ab >=> bc >=> cd | ||
|
||
instance (Functor f) => CProfunctor r (CStar r f) where | ||
cdimap ab cd (CStar bc) = CStar $ ab >=> bc >=> return . fmap (>>= cd) | ||
|
||
class (CProfunctor r p) => CStrong r p where | ||
cfirst' :: p a (Cont r b) -> p (a, c) (Cont r (b, c)) | ||
cfirst' = cdimap (return . swap) (return . swap) . csecond' | ||
|
||
csecond' :: p a (Cont r b) -> p (c, a) (Cont r (c, b)) | ||
csecond' = cdimap (return . swap) (return . swap) . cfirst' | ||
|
||
instance CStrong r (->) where | ||
cfirst' ab (a, c) = (,c) <$> ab a | ||
csecond' ab (c, a) = (c,) <$> ab a | ||
|
||
instance (Functor f) => CStrong r (CStar r f) where | ||
cfirst' (CStar afb) = CStar \(a, c) -> (fmap . fmap . fmap) (,c) (afb a) | ||
csecond' (CStar afb) = CStar \(c, a) -> (fmap . fmap . fmap) (c,) (afb a) | ||
|
||
class (CProfunctor r p) => CChoice r p where | ||
cleft' :: p a (Cont r b) -> p (Either a c) (Cont r (Either b c)) | ||
cleft' = cdimap (return . either Right Left) (return . either Right Left) . cright' | ||
|
||
cright' :: p a (Cont r b) -> p (Either c a) (Cont r (Either c b)) | ||
cright' = cdimap (return . either Right Left) (return . either Right Left) . cleft' | ||
|
||
instance CChoice r (->) where | ||
cleft' ab = either (fmap Left . ab) (return . Right) | ||
cright' ab = either (return . Left) (fmap Right . ab) | ||
|
||
instance (Applicative f) => CChoice r (CStar r f) where | ||
cleft' (CStar afb) = | ||
CStar $ | ||
either | ||
((fmap . fmap . fmap) Left . afb) | ||
(return . pure . return . Right) | ||
|
||
cright' (CStar afb) = | ||
CStar $ | ||
either | ||
(return . pure . return . Left) | ||
((fmap . fmap . fmap) Right . afb) | ||
|
||
class (CProfunctor r p) => CMonoidal r p where | ||
cunit :: p () (Cont r ()) | ||
cpar :: p a (Cont r b) -> p c (Cont r d) -> p (a, c) (Cont r (b, d)) | ||
|
||
instance CMonoidal r (->) where | ||
cunit () = return () | ||
cpar ab cd (a, c) = (,) <$> ab a <*> cd c | ||
|
||
instance (Applicative f) => CMonoidal r (CStar r f) where | ||
cunit = CStar $ \() -> return . pure . return $ () | ||
cpar (CStar afb) (CStar cfd) = | ||
CStar (\(a, c) -> (liftA2 . liftA2) (,) <$> afb a <*> cfd c) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
module Plutarch.Cont(PCont, pmatchCont) where | ||
|
||
import Control.Monad.Trans.Cont | ||
|
||
import Plutarch.Core | ||
|
||
type PCont edsl r = Cont (Term edsl r) | ||
|
||
pmatchCont :: | ||
( | ||
PConstructable edsl a, | ||
IsPType edsl r | ||
) => | ||
(PConcrete edsl a -> PCont edsl r b) -> | ||
Term edsl a -> | ||
PCont edsl r b | ||
pmatchCont cnt t = cont \c -> pmatch t \con -> runCont (cnt con) c |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Maybe this should still be
p b c
andp a d
.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.
Then
CProfunctor r ->
would not be implementable, but you could make a newtype where it is implementable.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.
I did try that. It is more elegant, but breaks too many things.