From 9c7e81f874825b3455f869f435cb7b4e9be1b0f5 Mon Sep 17 00:00:00 2001 From: Alex Gryzlov Date: Fri, 27 Jul 2018 12:53:50 +0300 Subject: [PATCH 001/126] fix for latest idris, helper --- src/Data/Profunctor.idr | 6 +++--- src/Data/Profunctor/Fold.idr | 9 +++++++-- src/Data/Profunctor/Lens.idr | 24 ++++++++++++++---------- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/Data/Profunctor.idr b/src/Data/Profunctor.idr index a999c7b..8c4ce00 100644 --- a/src/Data/Profunctor.idr +++ b/src/Data/Profunctor.idr @@ -37,8 +37,8 @@ interface Profunctor (p : Type -> Type -> Type) where rmap = dimap id implementation Monad m => Profunctor (Kleislimorphism m) where - dimap f g (Kleisli h) = Kleisli $ liftA g . h . f - + dimap f g (Kleisli h) = Kleisli $ \a => liftA g $ h $ f a + ||| An injective (->) ||| ||| ````idris example @@ -92,7 +92,7 @@ record UpStarred (f : Type -> Type) d c where runUpStar : d -> f c implementation Functor f => Profunctor (UpStarred f) where - dimap ab cd (UpStar bfc) = UpStar $ map cd . bfc . ab + dimap ab cd (UpStar bfc) = UpStar $ \a => map cd $ bfc $ ab a implementation Functor f => Functor (UpStarred f a) where map = rmap diff --git a/src/Data/Profunctor/Fold.idr b/src/Data/Profunctor/Fold.idr index 77b3028..ee54dbf 100644 --- a/src/Data/Profunctor/Fold.idr +++ b/src/Data/Profunctor/Fold.idr @@ -88,8 +88,11 @@ implementation Num n => Num (L a n) where implementation Neg n => Neg (L a n) where (-) = liftA2 (-) + negate = map negate + +implementation Abs n => Abs (L a n) where abs = map abs - negate = map negate + ||| An `L` to calculate the size of a `Foldable` container length : Num a => L _ a @@ -236,8 +239,10 @@ implementation Num n => Num (R a n) where implementation Neg n => Neg (R a n) where (-) = liftA2 (-) + negate = map negate + +implementation Abs n => Abs (R a n) where abs = map abs - negate = map negate implementation Group m => Group (R a m) where inverse = map inverse diff --git a/src/Data/Profunctor/Lens.idr b/src/Data/Profunctor/Lens.idr index bec9906..a3b823d 100644 --- a/src/Data/Profunctor/Lens.idr +++ b/src/Data/Profunctor/Lens.idr @@ -31,16 +31,20 @@ Lens' : Lensing p => Type -> Type -> Type Lens' {p} = Simple $ Lens {p} ||| Build a `Lens` out of a function. Note this takes one argument, not two -lens : Lensing p => (s -> (b -> t, a)) -> Lens {p} s t a b -lens f = lmap f . strength +lens' : Lensing p => (s -> (b -> t, a)) -> Lens {p} s t a b +lens' f = lmap f . strength + +||| Build a `Lens` out of getter and setter +lens : Lensing p => (s -> a) -> (s -> b -> t) -> Lens {p} s t a b +lens gt st = lens' $ \s => (\b => st s b, gt s) ||| Build a function to look at stuff from a Lens -view : Lens {p=Forgotten a} s _ a _ -> s -> a +view : Lens {p=Forgotten a} s t a b -> s -> a view = runForget . (\f => f $ Forget id) infixl 8 ^. ||| Infix synonym for `view` -(^.) : Lens {p=Forgotten a} s _ a _ -> s -> a +(^.) : Lens {p=Forgotten a} s t a b -> s -> a (^.) = view ||| Build a function to `map` from a Lens @@ -98,27 +102,27 @@ infixr 4 <$~ ||| A Lens for the first element of a tuple _1 : Lensing p => Lens {p} (a, b) (x, b) a x -_1 = lens $ \(a,b) => (flip MkPair b, a) +_1 = lens' $ \(a,b) => (flip MkPair b, a) ||| A Lens for the second element of a tuple _2 : Lensing p => Lens {p} (b, a) (b, x) a x -_2 = lens $ \(b,a) => (MkPair b, a) +_2 = lens' $ \(b,a) => (MkPair b, a) ||| A Lens for the first element of a non-empty vector _vCons : Lensing p => Lens {p} (Vect (S n) a) (Vect (S n) b) (a, Vect n a) (b, Vect n b) -_vCons = lens $ \(x::xs) => (uncurry (::), (x,xs)) +_vCons = lens' $ \(x::xs) => (uncurry (::), (x,xs)) ||| A Lens for the nth element of a big-enough vector _vNth : Lensing p => {m : Nat} -> (n : Fin (S m)) -> Lens {p} (Vect (S m) a) (Vect (S m) b) (a, Vect m a) (b, Vect m b) -_vNth n = lens $ \v => (uncurry $ insertAt n, (index n v, deleteAt n v)) +_vNth n = lens' $ \v => (uncurry $ insertAt n, (index n v, deleteAt n v)) ||| A Lens for the nth element of a big-enough heterogenous vector _hVNth : Lensing p => (i : Fin (S l)) -> Lens {p} (HVect us) (HVect vs) (index i us, HVect (deleteAt i us)) (index i vs, HVect (deleteAt i vs)) -_hVNth n = lens $ \v => +_hVNth n = lens' $ \v => (believe_me . uncurry (insertAt' n), (index n v, deleteAt n v)) where insertAt' : (i : Fin (S l)) -> a -> HVect us -> HVect (insertAt i a us) insertAt' FZ y xs = y :: xs @@ -127,4 +131,4 @@ _hVNth n = lens $ \v => ||| Everything has a `()` in it devoid : Lensing p => Lens' {p} a () -devoid = lens $ flip MkPair () . const +devoid = lens' $ flip MkPair () . const From 6cf50989a7c5f4b8a3a9f7e1ea10a28b6a8bd701 Mon Sep 17 00:00:00 2001 From: Alex Gryzlov Date: Mon, 30 Jul 2018 16:17:49 +0300 Subject: [PATCH 002/126] Traversal/Index/At --- profunctors.ipkg | 3 +++ src/Data/Profunctor.idr | 12 ++++++++++++ src/Data/Profunctor/Index.idr | 15 +++++++++++++++ src/Data/Profunctor/Lens.idr | 4 ++-- src/Data/Profunctor/Lens/At.idr | 15 +++++++++++++++ src/Data/Profunctor/Traversal.idr | 14 ++++++++++++++ 6 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 src/Data/Profunctor/Index.idr create mode 100644 src/Data/Profunctor/Lens/At.idr create mode 100644 src/Data/Profunctor/Traversal.idr diff --git a/profunctors.ipkg b/profunctors.ipkg index 20992d3..61475ad 100644 --- a/profunctors.ipkg +++ b/profunctors.ipkg @@ -9,9 +9,12 @@ modules = Data.Profunctor , Data.Profunctor.Composition , Data.Profunctor.Fold , Data.Profunctor.Iso + , Data.Profunctor.Index , Data.Profunctor.Lens + , Data.Profunctor.Lens.At , Data.Profunctor.Prism , Data.Profunctor.Trace + , Data.Profunctor.Traversal , Data.Verified.Profunctor opts = "-p contrib" diff --git a/src/Data/Profunctor.idr b/src/Data/Profunctor.idr index 8c4ce00..c965057 100644 --- a/src/Data/Profunctor.idr +++ b/src/Data/Profunctor.idr @@ -1,5 +1,6 @@ module Data.Profunctor +import Control.Monad.Identity import Control.Arrow import Control.Category import Data.Morphisms @@ -276,4 +277,15 @@ implementation Monoid r => Choice (Forgotten r) where left' (Forget k) = Forget . either k $ const neutral right' (Forget k) = Forget . flip either k $ const neutral + +||| Profunctors that support polymorphic traversals +interface (Strong p, Choice p) => Wander (p : Type -> Type -> Type) where + wander : ({f : Type -> Type} -> Applicative f => (a -> f b) -> s -> f t) -> p a b -> p s t + +Wander Arr where + wander t (MkArr f) = MkArr $ runIdentity . t (%implementation) (Id . f) + +Applicative f => Wander (UpStarred f) where + wander @{ap} t (UpStar f) = UpStar $ t ap f + -- }}} diff --git a/src/Data/Profunctor/Index.idr b/src/Data/Profunctor/Index.idr new file mode 100644 index 0000000..73615d0 --- /dev/null +++ b/src/Data/Profunctor/Index.idr @@ -0,0 +1,15 @@ +module Data.Profunctor.Index + +import Data.SortedMap +import Data.Profunctor +import Data.Profunctor.Traversal + +%default total +%access public export + +interface Wander p => Index (p : Type -> Type -> Type) (m : Type) (a : Type) (b : Type) where + ix : a -> Traversal' {p} m b + +Ord k => Index Arr (SortedMap k v) k v where + -- magical f1 + ix k = wander $ \coalg, m => maybe (pure {f=f1} m) (map {f=f1} (\v => insert k v m) . coalg) (lookup k m) diff --git a/src/Data/Profunctor/Lens.idr b/src/Data/Profunctor/Lens.idr index a3b823d..358796e 100644 --- a/src/Data/Profunctor/Lens.idr +++ b/src/Data/Profunctor/Lens.idr @@ -57,12 +57,12 @@ infixr 4 &~ (&~) = over ||| Set something to a specific value with a Lens -set : Lens {p=Arr} s t _ b -> b -> s -> t +set : Lens {p=Arr} s t a b -> b -> s -> t set = (. const) . over infixr 4 .~ ||| Infix synonym for `set` -(.~) : Lens {p=Arr} s t _ b -> b -> s -> t +(.~) : Lens {p=Arr} s t a b -> b -> s -> t (.~) = set infixr 4 +~ diff --git a/src/Data/Profunctor/Lens/At.idr b/src/Data/Profunctor/Lens/At.idr new file mode 100644 index 0000000..f4f6c7b --- /dev/null +++ b/src/Data/Profunctor/Lens/At.idr @@ -0,0 +1,15 @@ +module Data.Profunctor.Lens.At + +import Data.SortedMap +import Data.Profunctor +import Data.Profunctor.Lens +import Data.Profunctor.Index + +%default total +%access public export + +interface (Lensing p, Index p m a b) => At (p : Type -> Type -> Type) (m : Type) (a : Type) (b : Type) where + at : a -> Lens' {p} m (Maybe b) + +Ord k => At Arr (SortedMap k v) k v where + at k = lens (lookup k) (\m => maybe (delete k m) (\v => insert k v m)) diff --git a/src/Data/Profunctor/Traversal.idr b/src/Data/Profunctor/Traversal.idr new file mode 100644 index 0000000..8fe7f46 --- /dev/null +++ b/src/Data/Profunctor/Traversal.idr @@ -0,0 +1,14 @@ +module Data.Profunctor.Fold + +import Data.Profunctor +import Data.Profunctor.Iso + +%default total +%access public export + +Traversal : Wander p => Type -> Type -> Type -> Type -> Type +Traversal {p} = preIso {p} + +||| A Traversal that does not change types +Traversal' : Wander p => Type -> Type -> Type +Traversal' {p} = Simple $ Traversal {p} \ No newline at end of file From fe3a5cdb3bcb89776705305a857c58d260f78111 Mon Sep 17 00:00:00 2001 From: Alex Gryzlov Date: Mon, 30 Jul 2018 17:40:46 +0300 Subject: [PATCH 003/126] generalize Index/At for Maps/Sets --- src/Data/Profunctor.idr | 15 ++++++++++++++- src/Data/Profunctor/Index.idr | 7 ++++++- src/Data/Profunctor/Lens/At.idr | 10 +++++++++- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/Data/Profunctor.idr b/src/Data/Profunctor.idr index c965057..9eeba33 100644 --- a/src/Data/Profunctor.idr +++ b/src/Data/Profunctor.idr @@ -7,6 +7,17 @@ import Data.Morphisms %access public export +record Const (a : Type) (b : Type) where + constructor MkConst + runConst : a + +Functor (Const m) where + map _ (MkConst v) = MkConst v + +Monoid m => Applicative (Const m) where + pure _ = MkConst neutral + (MkConst a) <*> (MkConst b) = MkConst (a <+> b) + ||| Profunctors ||| @p The action of the Profunctor on pairs of objects interface Profunctor (p : Type -> Type -> Type) where @@ -277,7 +288,6 @@ implementation Monoid r => Choice (Forgotten r) where left' (Forget k) = Forget . either k $ const neutral right' (Forget k) = Forget . flip either k $ const neutral - ||| Profunctors that support polymorphic traversals interface (Strong p, Choice p) => Wander (p : Type -> Type -> Type) where wander : ({f : Type -> Type} -> Applicative f => (a -> f b) -> s -> f t) -> p a b -> p s t @@ -288,4 +298,7 @@ Wander Arr where Applicative f => Wander (UpStarred f) where wander @{ap} t (UpStar f) = UpStar $ t ap f +Monoid r => Wander (Forgotten r) where + wander t (Forget r) = Forget $ runConst . t (%implementation) (MkConst . r) + -- }}} diff --git a/src/Data/Profunctor/Index.idr b/src/Data/Profunctor/Index.idr index 73615d0..ce97c70 100644 --- a/src/Data/Profunctor/Index.idr +++ b/src/Data/Profunctor/Index.idr @@ -1,6 +1,7 @@ module Data.Profunctor.Index import Data.SortedMap +import Data.SortedSet import Data.Profunctor import Data.Profunctor.Traversal @@ -10,6 +11,10 @@ import Data.Profunctor.Traversal interface Wander p => Index (p : Type -> Type -> Type) (m : Type) (a : Type) (b : Type) where ix : a -> Traversal' {p} m b -Ord k => Index Arr (SortedMap k v) k v where +(Wander p, Ord k) => Index p (SortedMap k v) k v where -- magical f1 ix k = wander $ \coalg, m => maybe (pure {f=f1} m) (map {f=f1} (\v => insert k v m) . coalg) (lookup k m) + +(Wander p, Ord a) => Index p (SortedSet a) a () where + -- magical f1 + ix x = wander $ \coalg => pure {f=f1} . SortedSet.insert x \ No newline at end of file diff --git a/src/Data/Profunctor/Lens/At.idr b/src/Data/Profunctor/Lens/At.idr index f4f6c7b..cd14ec6 100644 --- a/src/Data/Profunctor/Lens/At.idr +++ b/src/Data/Profunctor/Lens/At.idr @@ -1,6 +1,7 @@ module Data.Profunctor.Lens.At import Data.SortedMap +import Data.SortedSet import Data.Profunctor import Data.Profunctor.Lens import Data.Profunctor.Index @@ -11,5 +12,12 @@ import Data.Profunctor.Index interface (Lensing p, Index p m a b) => At (p : Type -> Type -> Type) (m : Type) (a : Type) (b : Type) where at : a -> Lens' {p} m (Maybe b) -Ord k => At Arr (SortedMap k v) k v where +(Wander p, Lensing p, Ord k) => At p (SortedMap k v) k v where at k = lens (lookup k) (\m => maybe (delete k m) (\v => insert k v m)) + +(Wander p, Lensing p, Ord a) => At p (SortedSet a) a Unit where + at x = lens get (flip update) + where + get xs = if contains x xs then Just () else Nothing + update Nothing = delete x + update (Just _) = insert x \ No newline at end of file From 75ae61059ad743445c14227f16d02be3172eaae6 Mon Sep 17 00:00:00 2001 From: Alex Gryzlov Date: Thu, 4 Jul 2019 00:53:23 +0300 Subject: [PATCH 004/126] fix Choice (Kleislimorphism m) --- src/Data/Profunctor.idr | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Data/Profunctor.idr b/src/Data/Profunctor.idr index 9eeba33..549e4c5 100644 --- a/src/Data/Profunctor.idr +++ b/src/Data/Profunctor.idr @@ -267,10 +267,10 @@ interface Profunctor p => Choice (p : Type -> Type -> Type) where right' = dimap mirror mirror . left' implementation Monad m => Choice (Kleislimorphism m) where - left' f = Kleisli $ either (applyKleisli $ f >>> arrow Left) - (applyKleisli $ arrow id >>> arrow Right) - right' f = Kleisli $ either (applyKleisli $ arrow id >>> arrow Left) - (applyKleisli $ f >>> arrow Right) + left' f = Kleisli $ either (applyKleisli $ f >>> arrow Left) + (applyKleisli $ arrow id >>> arrow Right) + right' f = Kleisli $ either (applyKleisli {f=m} $ arrow id >>> arrow Left) + (applyKleisli $ f >>> arrow Right) implementation Choice Arr where left' (MkArr f) = MkArr $ either (Left . f) Right From c0063ceee3bbfc2cadb7780f2b021f3fe26ed6ea Mon Sep 17 00:00:00 2001 From: Alex Gryzlov Date: Fri, 5 Jul 2019 17:36:55 +0300 Subject: [PATCH 005/126] Arr -> Morphism --- src/Data/Profunctor.idr | 44 ++++++++-------------------------- src/Data/Profunctor/Closed.idr | 5 ++-- src/Data/Profunctor/Lens.idr | 29 +++++++++++----------- src/Data/Profunctor/Prism.idr | 5 ++-- src/Data/Profunctor/Unsafe.idr | 2 +- 5 files changed, 32 insertions(+), 53 deletions(-) diff --git a/src/Data/Profunctor.idr b/src/Data/Profunctor.idr index 549e4c5..f5a58f8 100644 --- a/src/Data/Profunctor.idr +++ b/src/Data/Profunctor.idr @@ -50,33 +50,9 @@ interface Profunctor (p : Type -> Type -> Type) where implementation Monad m => Profunctor (Kleislimorphism m) where dimap f g (Kleisli h) = Kleisli $ \a => liftA g $ h $ f a - -||| An injective (->) -||| -||| ````idris example -||| believe_me : Arr a b -||| ```` -||| -record Arr a b where - constructor MkArr - runArr : (a -> b) -implementation Category Arr where - id = assert_total id - (.) = assert_total (.) - -implementation Arrow Arr where - arrow = MkArr - first = MkArr . (\f,(a,b) => (f a,b)) . runArr - second = MkArr . (\f,(a,b) => (a,f b)) . runArr - (MkArr f) *** (MkArr g) = MkArr $ \(a,b) => (f a, g b) - (MkArr f) &&& (MkArr g) = MkArr $ \a => (f a, g a) - -implementation Profunctor Arr where - dimap f g (MkArr h) = MkArr $ g . h . f - -implementation Functor (Arr a) where - map = rmap +implementation Profunctor Morphism where + dimap f g (Mor h) = Mor $ g . h . f ||| A method of attaching a phantom type as a "tag" record Tagged a b where @@ -226,9 +202,9 @@ implementation Monad m => Strong (Kleislimorphism m) where first' (Kleisli f) = Kleisli $ \ac => f (fst ac) >>= \b => pure (b, snd ac) second' (Kleisli f) = Kleisli $ \ca => f (snd ca) >>= pure . MkPair (fst ca) -implementation Strong Arr where - first' (MkArr f) = MkArr $ \(a,c) => (f a, c) - second' (MkArr f) = MkArr $ \(c,a) => (c, f a) +implementation Strong Morphism where + first' (Mor f) = Mor $ \(a,c) => (f a, c) + second' (Mor f) = Mor $ \(c,a) => (c, f a) implementation Functor m => Strong (UpStarred m) where first' (UpStar f) = UpStar $ \ac => map (\b' => (b', snd ac)) . f $ fst ac @@ -272,9 +248,9 @@ implementation Monad m => Choice (Kleislimorphism m) where right' f = Kleisli $ either (applyKleisli {f=m} $ arrow id >>> arrow Left) (applyKleisli $ f >>> arrow Right) -implementation Choice Arr where - left' (MkArr f) = MkArr $ either (Left . f) Right - right' (MkArr f) = MkArr $ either Left (Right . f) +implementation Choice Morphism where + left' (Mor f) = Mor $ either (Left . f) Right + right' (Mor f) = Mor $ either Left (Right . f) implementation Choice Tagged where left' = Tag . Left . runTagged @@ -292,8 +268,8 @@ implementation Monoid r => Choice (Forgotten r) where interface (Strong p, Choice p) => Wander (p : Type -> Type -> Type) where wander : ({f : Type -> Type} -> Applicative f => (a -> f b) -> s -> f t) -> p a b -> p s t -Wander Arr where - wander t (MkArr f) = MkArr $ runIdentity . t (%implementation) (Id . f) +Wander Morphism where + wander t (Mor f) = Mor $ runIdentity . t (%implementation) (Id . f) Applicative f => Wander (UpStarred f) where wander @{ap} t (UpStar f) = UpStar $ t ap f diff --git a/src/Data/Profunctor/Closed.idr b/src/Data/Profunctor/Closed.idr index d910b92..824655e 100644 --- a/src/Data/Profunctor/Closed.idr +++ b/src/Data/Profunctor/Closed.idr @@ -2,6 +2,7 @@ module Data.Profunctor.Closed import Control.Arrow import Control.Category +import Data.Morphisms import Data.Profunctor import Data.Profunctor.Unsafe @@ -17,8 +18,8 @@ interface Profunctor p => Closed (p : Type -> Type -> Type) where ||| closed : {x : _} -> p a b -> p (x -> a) (x -> b) -implementation Closed Arr where - closed = MkArr . (.) . runArr +implementation Closed Morphism where + closed = Mor . (.) . applyMor implementation Functor f => Closed (DownStarred f) where closed (DownStar fab) = DownStar $ \fxa,x => fab $ map (\f => f x) fxa diff --git a/src/Data/Profunctor/Lens.idr b/src/Data/Profunctor/Lens.idr index 358796e..4c92553 100644 --- a/src/Data/Profunctor/Lens.idr +++ b/src/Data/Profunctor/Lens.idr @@ -2,6 +2,7 @@ module Data.Profunctor.Lens import Data.Fin import Data.HVect +import Data.Morphisms import Data.Profunctor import Data.Profunctor.Iso import Data.Vect @@ -19,8 +20,8 @@ implementation Lensing (Forgotten r) where implementation Functor f => Lensing (UpStarred f) where strength (UpStar f) = UpStar . uncurry $ (. f) . (<$>) -implementation Lensing Arr where - strength = MkArr . uncurry . flip (.) . runArr +implementation Lensing Morphism where + strength = Mor . uncurry . flip (.) . applyMor ||| A Lens family, strictly speaking, or a polymorphic lens. Lens : Lensing p => Type -> Type -> Type -> Type -> Type @@ -48,56 +49,56 @@ infixl 8 ^. (^.) = view ||| Build a function to `map` from a Lens -over : Lens {p=Arr} s t a b -> (a -> b) -> s -> t -over = (runArr .) . (. MkArr) +over : Lens {p=Morphism} s t a b -> (a -> b) -> s -> t +over = (applyMor .) . (. Mor) infixr 4 &~ ||| Infix synonym for `over` -(&~) : Lens {p=Arr} s t a b -> (a -> b) -> s -> t +(&~) : Lens {p=Morphism} s t a b -> (a -> b) -> s -> t (&~) = over ||| Set something to a specific value with a Lens -set : Lens {p=Arr} s t a b -> b -> s -> t +set : Lens {p=Morphism} s t a b -> b -> s -> t set = (. const) . over infixr 4 .~ ||| Infix synonym for `set` -(.~) : Lens {p=Arr} s t a b -> b -> s -> t +(.~) : Lens {p=Morphism} s t a b -> b -> s -> t (.~) = set infixr 4 +~ ||| Increment the target of a lens by a number -(+~) : Num a => Lens {p=Arr} s t a a -> a -> s -> t +(+~) : Num a => Lens {p=Morphism} s t a a -> a -> s -> t (+~) = (. (+)) . over infixr 4 -~ ||| Decrement the target of a lens by a number -(-~) : Neg a => Lens {p=Arr} s t a a -> a -> s -> t +(-~) : Neg a => Lens {p=Morphism} s t a a -> a -> s -> t (-~) = (. (-)) . over infixr 4 *~ ||| Multiply the target of a lens by a number -(*~) : Num a => Lens {p=Arr} s t a a -> a -> s -> t +(*~) : Num a => Lens {p=Morphism} s t a a -> a -> s -> t (*~) = (. (*)) . over infixr 4 /~ ||| Divide the target of a lens by a number -(/~) : Lens {p=Arr} s t Double Double -> Double -> s -> t +(/~) : Lens {p=Morphism} s t Double Double -> Double -> s -> t (/~) = (. (/)) . over infixr 4 <+>~ ||| Associatively combine the target of a Lens with another value -(<+>~) : Semigroup a => Lens {p=Arr} s t a a -> a -> s -> t +(<+>~) : Semigroup a => Lens {p=Morphism} s t a a -> a -> s -> t (<+>~) = (. (<+>)) . over infixr 4 $>~ ||| Rightwards sequence the target of a lens with an applicative -($>~) : Applicative f => Lens {p=Arr} s t (f a) (f a) -> f a -> s -> t +($>~) : Applicative f => Lens {p=Morphism} s t (f a) (f a) -> f a -> s -> t ($>~) l = over l . (*>) infixr 4 <$~ ||| Rightwards sequence the target of a lens with an applicative -(<$~) : Applicative f => Lens {p=Arr} s t (f a) (f a) -> f a -> s -> t +(<$~) : Applicative f => Lens {p=Morphism} s t (f a) (f a) -> f a -> s -> t (<$~) l = over l . (<*) ||| A Lens for the first element of a tuple diff --git a/src/Data/Profunctor/Prism.idr b/src/Data/Profunctor/Prism.idr index 0f412c2..db032d1 100644 --- a/src/Data/Profunctor/Prism.idr +++ b/src/Data/Profunctor/Prism.idr @@ -1,5 +1,6 @@ module Data.Profunctor.Prism +import Data.Morphisms import Data.Profunctor import Data.Profunctor.Iso @@ -10,8 +11,8 @@ interface Choice p => Prisming (p : Type -> Type -> Type) where costrength : p a b -> p (Either b a) b costrength = rmap (either id id) . right' -implementation Prisming Arr where - costrength = MkArr . either id . Delay . runArr +implementation Prisming Morphism where + costrength = Mor . either id . Delay . applyMor implementation Monoid r => Prisming (Forgotten r) where costrength p = Forget . either (const neutral) $ runForget p diff --git a/src/Data/Profunctor/Unsafe.idr b/src/Data/Profunctor/Unsafe.idr index 612e5dc..e55683b 100644 --- a/src/Data/Profunctor/Unsafe.idr +++ b/src/Data/Profunctor/Unsafe.idr @@ -19,7 +19,7 @@ interface Profunctor p => UnsafeProfunctor (p : Type -> Type -> Type) where (.#) : p b c -> (a -> b) -> p a c (.#) = flip lmap -implementation UnsafeProfunctor Arr where +implementation UnsafeProfunctor Morphism where (#.) = const believe_me (.#) = const . believe_me From 49666c3125118d55db909eecbfa4f6ad83751842 Mon Sep 17 00:00:00 2001 From: Alex Gryzlov Date: Fri, 5 Jul 2019 21:53:29 +0300 Subject: [PATCH 006/126] flip arguments of ^. --- src/Data/Profunctor/Lens.idr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Data/Profunctor/Lens.idr b/src/Data/Profunctor/Lens.idr index 4c92553..ef8f7ca 100644 --- a/src/Data/Profunctor/Lens.idr +++ b/src/Data/Profunctor/Lens.idr @@ -45,8 +45,8 @@ view = runForget . (\f => f $ Forget id) infixl 8 ^. ||| Infix synonym for `view` -(^.) : Lens {p=Forgotten a} s t a b -> s -> a -(^.) = view +(^.) : s -> Lens {p=Forgotten a} s t a b -> a +(^.) = flip view ||| Build a function to `map` from a Lens over : Lens {p=Morphism} s t a b -> (a -> b) -> s -> t From b5311ddda8813e0069da9e7ac0c4069a613ae839 Mon Sep 17 00:00:00 2001 From: Alex Gryzlov Date: Fri, 5 Jul 2019 22:28:29 +0300 Subject: [PATCH 007/126] add elba manifest --- .gitignore | 2 ++ elba.toml | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 elba.toml diff --git a/.gitignore b/.gitignore index c28bc7c..f33345a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ *.ibc *.o +target/ +elba.lock \ No newline at end of file diff --git a/elba.toml b/elba.toml new file mode 100644 index 0000000..3f2f31c --- /dev/null +++ b/elba.toml @@ -0,0 +1,24 @@ +[package] +name = "japesinator/Idris-Profunctors" +version = "0.1.0" +authors = [] + +[targets.lib] +path = "src" +name = "profunctors" +mods = [ "Data.Profunctor" + , "Data.Profunctor.Cayley" + , "Data.Profunctor.Closed" + , "Data.Profunctor.Codensity" + , "Data.Profunctor.Composition" + , "Data.Profunctor.Fold" + , "Data.Profunctor.Iso" + , "Data.Profunctor.Index" + , "Data.Profunctor.Lens" + , "Data.Profunctor.Lens.At" + , "Data.Profunctor.Prism" + , "Data.Profunctor.Trace" + , "Data.Profunctor.Traversal" + , "Data.Verified.Profunctor" + ] +idris_opts = ["-p", "contrib"] From 5dde409cbc45dde438f3f12412360aad74b006a6 Mon Sep 17 00:00:00 2001 From: Alex Gryzlov Date: Sun, 7 Jul 2019 19:38:50 +0300 Subject: [PATCH 008/126] add operators --- profunctors.ipkg | 2 ++ src/Data/Profunctor/Lens.idr | 19 ++++++++++++++++++- src/Data/Profunctor/Traversal.idr | 8 +++++++- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/profunctors.ipkg b/profunctors.ipkg index 61475ad..0d85ff9 100644 --- a/profunctors.ipkg +++ b/profunctors.ipkg @@ -17,4 +17,6 @@ modules = Data.Profunctor , Data.Profunctor.Traversal , Data.Verified.Profunctor +pkgs = bifunctors + opts = "-p contrib" diff --git a/src/Data/Profunctor/Lens.idr b/src/Data/Profunctor/Lens.idr index ef8f7ca..f5b3855 100644 --- a/src/Data/Profunctor/Lens.idr +++ b/src/Data/Profunctor/Lens.idr @@ -43,11 +43,22 @@ lens gt st = lens' $ \s => (\b => st s b, gt s) view : Lens {p=Forgotten a} s t a b -> s -> a view = runForget . (\f => f $ Forget id) +foldMapOf : Lens {p=Forgotten r} s t a b -> (a -> r) -> s -> r +foldMapOf l f = runForget $ l $ Forget f + +||| Create a getter from arbitrary function `s -> a`. +getter : (s -> a) -> Lens {p=Forgotten a} s t a b +getter k = \(Forget aa) => Forget $ aa . k + infixl 8 ^. ||| Infix synonym for `view` (^.) : s -> Lens {p=Forgotten a} s t a b -> a (^.) = flip view +infixl 8 ^? +(^?) : s -> Lens {p=Forgotten $ Maybe a} s t a b -> Maybe a +s ^? l = foldMapOf l Just s + ||| Build a function to `map` from a Lens over : Lens {p=Morphism} s t a b -> (a -> b) -> s -> t over = (applyMor .) . (. Mor) @@ -57,6 +68,9 @@ infixr 4 &~ (&~) : Lens {p=Morphism} s t a b -> (a -> b) -> s -> t (&~) = over +sets : ((a -> b) -> s -> t) -> Lens {p=Morphism} s t a b +sets l = \(Mor f) => Mor $ l f + ||| Set something to a specific value with a Lens set : Lens {p=Morphism} s t a b -> b -> s -> t set = (. const) . over @@ -66,6 +80,9 @@ infixr 4 .~ (.~) : Lens {p=Morphism} s t a b -> b -> s -> t (.~) = set +mapped : Functor f => Lens {p=Morphism} (f a) (f b) a b +mapped = sets map + infixr 4 +~ ||| Increment the target of a lens by a number (+~) : Num a => Lens {p=Morphism} s t a a -> a -> s -> t @@ -83,7 +100,7 @@ infixr 4 *~ infixr 4 /~ ||| Divide the target of a lens by a number -(/~) : Lens {p=Morphism} s t Double Double -> Double -> s -> t +(/~) : Fractional a => Lens {p=Morphism} s t a a -> a -> s -> t (/~) = (. (/)) . over infixr 4 <+>~ diff --git a/src/Data/Profunctor/Traversal.idr b/src/Data/Profunctor/Traversal.idr index 8fe7f46..0d03a5e 100644 --- a/src/Data/Profunctor/Traversal.idr +++ b/src/Data/Profunctor/Traversal.idr @@ -2,6 +2,9 @@ module Data.Profunctor.Fold import Data.Profunctor import Data.Profunctor.Iso +import Data.Morphisms +import Data.Bitraversable +import Control.Monad.Identity %default total %access public export @@ -11,4 +14,7 @@ Traversal {p} = preIso {p} ||| A Traversal that does not change types Traversal' : Wander p => Type -> Type -> Type -Traversal' {p} = Simple $ Traversal {p} \ No newline at end of file +Traversal' {p} = Simple $ Traversal {p} + +both : Bitraversable r => Traversal {p=Morphism} (r a a) (r b b) a b +both (Mor f) = Mor $ runIdentity . bitraverse {f=Identity} (Id . f) (Id . f) \ No newline at end of file From d9650126ebffbd1011c114d4eb3eda18e89fe865 Mon Sep 17 00:00:00 2001 From: Alex Gryzlov Date: Sun, 7 Jul 2019 21:05:15 +0300 Subject: [PATCH 009/126] expand index/at --- src/Data/Profunctor/Index.idr | 3 +++ src/Data/Profunctor/Lens/At.idr | 9 ++++++++- src/Data/Profunctor/Prism.idr | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Data/Profunctor/Index.idr b/src/Data/Profunctor/Index.idr index ce97c70..764baa7 100644 --- a/src/Data/Profunctor/Index.idr +++ b/src/Data/Profunctor/Index.idr @@ -11,6 +11,9 @@ import Data.Profunctor.Traversal interface Wander p => Index (p : Type -> Type -> Type) (m : Type) (a : Type) (b : Type) where ix : a -> Traversal' {p} m b +Wander p => Index p (Maybe a) () a where + ix {a} () = wander $ traverse {f=f1} {t=Maybe} + (Wander p, Ord k) => Index p (SortedMap k v) k v where -- magical f1 ix k = wander $ \coalg, m => maybe (pure {f=f1} m) (map {f=f1} (\v => insert k v m) . coalg) (lookup k m) diff --git a/src/Data/Profunctor/Lens/At.idr b/src/Data/Profunctor/Lens/At.idr index cd14ec6..23b7642 100644 --- a/src/Data/Profunctor/Lens/At.idr +++ b/src/Data/Profunctor/Lens/At.idr @@ -1,5 +1,6 @@ module Data.Profunctor.Lens.At +import Data.Morphisms import Data.SortedMap import Data.SortedSet import Data.Profunctor @@ -20,4 +21,10 @@ interface (Lensing p, Index p m a b) => At (p : Type -> Type -> Type) (m : Type) where get xs = if contains x xs then Just () else Nothing update Nothing = delete x - update (Just _) = insert x \ No newline at end of file + update (Just _) = insert x + +(Wander p, Lensing p) => At p (Maybe a) () a where + at () = id + +sans : At Morphism m a b => a -> m -> m +sans {m} {a} {b} k = at {p=Morphism} {m} {a} {b} k .~ Nothing diff --git a/src/Data/Profunctor/Prism.idr b/src/Data/Profunctor/Prism.idr index db032d1..b0bcffe 100644 --- a/src/Data/Profunctor/Prism.idr +++ b/src/Data/Profunctor/Prism.idr @@ -54,7 +54,7 @@ preview : Prism {p=Forgotten (First a)} s _ a _ -> s -> Maybe a preview l = runFirst . runForget (l . Forget $ MkFirst . Just) ||| Build a function from a `Prism` to `map` -review : Prism {p=Tagged} _ t _ b -> b -> t +review : Prism {p=Tagged} s t a b -> b -> t review = (runTagged .) . (. Tag) ||| A `Prism` for the left half of an `Either` From 11761e5db865d04d45202f7569847e50702b53f6 Mon Sep 17 00:00:00 2001 From: Alex Gryzlov Date: Sun, 7 Jul 2019 21:14:00 +0300 Subject: [PATCH 010/126] syntax --- src/Data/Profunctor/Index.idr | 2 +- src/Data/Profunctor/Lens/At.idr | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Data/Profunctor/Index.idr b/src/Data/Profunctor/Index.idr index 764baa7..92d40dc 100644 --- a/src/Data/Profunctor/Index.idr +++ b/src/Data/Profunctor/Index.idr @@ -20,4 +20,4 @@ Wander p => Index p (Maybe a) () a where (Wander p, Ord a) => Index p (SortedSet a) a () where -- magical f1 - ix x = wander $ \coalg => pure {f=f1} . SortedSet.insert x \ No newline at end of file + ix x = wander $ \_ => pure {f=f1} . SortedSet.insert x \ No newline at end of file diff --git a/src/Data/Profunctor/Lens/At.idr b/src/Data/Profunctor/Lens/At.idr index 23b7642..c5302e2 100644 --- a/src/Data/Profunctor/Lens/At.idr +++ b/src/Data/Profunctor/Lens/At.idr @@ -13,18 +13,18 @@ import Data.Profunctor.Index interface (Lensing p, Index p m a b) => At (p : Type -> Type -> Type) (m : Type) (a : Type) (b : Type) where at : a -> Lens' {p} m (Maybe b) +(Wander p, Lensing p) => At p (Maybe a) () a where + at () = id + (Wander p, Lensing p, Ord k) => At p (SortedMap k v) k v where at k = lens (lookup k) (\m => maybe (delete k m) (\v => insert k v m)) -(Wander p, Lensing p, Ord a) => At p (SortedSet a) a Unit where +(Wander p, Lensing p, Ord a) => At p (SortedSet a) a () where at x = lens get (flip update) where get xs = if contains x xs then Just () else Nothing update Nothing = delete x update (Just _) = insert x -(Wander p, Lensing p) => At p (Maybe a) () a where - at () = id - sans : At Morphism m a b => a -> m -> m sans {m} {a} {b} k = at {p=Morphism} {m} {a} {b} k .~ Nothing From e71c599c9adef4a51800099cad1ba749407dea45 Mon Sep 17 00:00:00 2001 From: Alex Gryzlov Date: Sun, 7 Jul 2019 22:34:28 +0300 Subject: [PATCH 011/126] update --- elba.toml | 5 ++++- profunctors.ipkg | 2 +- src/Data/Profunctor/Lens.idr | 4 ++++ src/Data/Profunctor/Lens/At.idr | 7 ++++--- src/Data/Profunctor/Prism.idr | 4 ++++ src/Data/Profunctor/Traversal.idr | 3 +++ src/Data/Profunctor/{ => Traversal}/Index.idr | 6 +++--- 7 files changed, 23 insertions(+), 8 deletions(-) rename src/Data/Profunctor/{ => Traversal}/Index.idr (84%) diff --git a/elba.toml b/elba.toml index 3f2f31c..8eb955a 100644 --- a/elba.toml +++ b/elba.toml @@ -3,6 +3,9 @@ name = "japesinator/Idris-Profunctors" version = "0.1.0" authors = [] +[dependencies] +"japesinator/Idris-Bifunctors" = { git = "https://github.com/andrevidela/Idris-Bifunctors" } + [targets.lib] path = "src" name = "profunctors" @@ -13,12 +16,12 @@ mods = [ "Data.Profunctor" , "Data.Profunctor.Composition" , "Data.Profunctor.Fold" , "Data.Profunctor.Iso" - , "Data.Profunctor.Index" , "Data.Profunctor.Lens" , "Data.Profunctor.Lens.At" , "Data.Profunctor.Prism" , "Data.Profunctor.Trace" , "Data.Profunctor.Traversal" + , "Data.Profunctor.Traversal.Index" , "Data.Verified.Profunctor" ] idris_opts = ["-p", "contrib"] diff --git a/profunctors.ipkg b/profunctors.ipkg index 0d85ff9..6e80ba8 100644 --- a/profunctors.ipkg +++ b/profunctors.ipkg @@ -9,12 +9,12 @@ modules = Data.Profunctor , Data.Profunctor.Composition , Data.Profunctor.Fold , Data.Profunctor.Iso - , Data.Profunctor.Index , Data.Profunctor.Lens , Data.Profunctor.Lens.At , Data.Profunctor.Prism , Data.Profunctor.Trace , Data.Profunctor.Traversal + , Data.Profunctor.Traversal.Index , Data.Verified.Profunctor pkgs = bifunctors diff --git a/src/Data/Profunctor/Lens.idr b/src/Data/Profunctor/Lens.idr index f5b3855..2c59b6b 100644 --- a/src/Data/Profunctor/Lens.idr +++ b/src/Data/Profunctor/Lens.idr @@ -50,6 +50,10 @@ foldMapOf l f = runForget $ l $ Forget f getter : (s -> a) -> Lens {p=Forgotten a} s t a b getter k = \(Forget aa) => Forget $ aa . k +||| Combine two getters. +takeBoth : Lens {p=Forgotten a} s t a b -> Lens {p=Forgotten c} s t c d -> Lens {p=Forgotten (a, c)} s t (a, c) (b, d) +takeBoth l r = getter $ \s => (view l s, view r s) + infixl 8 ^. ||| Infix synonym for `view` (^.) : s -> Lens {p=Forgotten a} s t a b -> a diff --git a/src/Data/Profunctor/Lens/At.idr b/src/Data/Profunctor/Lens/At.idr index c5302e2..282af70 100644 --- a/src/Data/Profunctor/Lens/At.idr +++ b/src/Data/Profunctor/Lens/At.idr @@ -5,12 +5,13 @@ import Data.SortedMap import Data.SortedSet import Data.Profunctor import Data.Profunctor.Lens -import Data.Profunctor.Index +import Data.Profunctor.Traversal.Index %default total %access public export -interface (Lensing p, Index p m a b) => At (p : Type -> Type -> Type) (m : Type) (a : Type) (b : Type) where +||| Allows adding and deleting elements from "container-like" types +interface (Lensing p, Index p m a b) => At (p : Type -> Type -> Type) (m : Type) (a : Type) (b : Type) | m where at : a -> Lens' {p} m (Maybe b) (Wander p, Lensing p) => At p (Maybe a) () a where @@ -27,4 +28,4 @@ interface (Lensing p, Index p m a b) => At (p : Type -> Type -> Type) (m : Type) update (Just _) = insert x sans : At Morphism m a b => a -> m -> m -sans {m} {a} {b} k = at {p=Morphism} {m} {a} {b} k .~ Nothing +sans {m} k = at {p=Morphism} {m} k .~ Nothing diff --git a/src/Data/Profunctor/Prism.idr b/src/Data/Profunctor/Prism.idr index b0bcffe..df590d4 100644 --- a/src/Data/Profunctor/Prism.idr +++ b/src/Data/Profunctor/Prism.idr @@ -93,6 +93,10 @@ only a = prism (const a) $ \x => if x == a then Left x else Right () nearly : Prisming p => a -> (a -> Bool) -> Prism' {p} a () nearly a p = prism (const a) $ if p a then Left else const $ Right () +||| Checks whether an object would match a given `Prism` +is : Prism {p=Forgotten (First a)} s _ a _ -> s -> Bool +is = (isJust .) . preview + ||| Checks whether an object won't match a given `Prism` isn't : Prism {p=Forgotten (First a)} s _ a _ -> s -> Bool isn't = (isNothing .) . preview diff --git a/src/Data/Profunctor/Traversal.idr b/src/Data/Profunctor/Traversal.idr index 0d03a5e..17c084d 100644 --- a/src/Data/Profunctor/Traversal.idr +++ b/src/Data/Profunctor/Traversal.idr @@ -16,5 +16,8 @@ Traversal {p} = preIso {p} Traversal' : Wander p => Type -> Type -> Type Traversal' {p} = Simple $ Traversal {p} +traversed : (Wander p, Traversable t) => Traversal {p} (t a) (t b) a b +traversed {t} = wander $ traverse {f=f1} {t} + both : Bitraversable r => Traversal {p=Morphism} (r a a) (r b b) a b both (Mor f) = Mor $ runIdentity . bitraverse {f=Identity} (Id . f) (Id . f) \ No newline at end of file diff --git a/src/Data/Profunctor/Index.idr b/src/Data/Profunctor/Traversal/Index.idr similarity index 84% rename from src/Data/Profunctor/Index.idr rename to src/Data/Profunctor/Traversal/Index.idr index 92d40dc..2bfcc26 100644 --- a/src/Data/Profunctor/Index.idr +++ b/src/Data/Profunctor/Traversal/Index.idr @@ -1,4 +1,4 @@ -module Data.Profunctor.Index +module Data.Profunctor.Traversal.Index import Data.SortedMap import Data.SortedSet @@ -8,11 +8,11 @@ import Data.Profunctor.Traversal %default total %access public export -interface Wander p => Index (p : Type -> Type -> Type) (m : Type) (a : Type) (b : Type) where +interface Wander p => Index (p : Type -> Type -> Type) (m : Type) (a : Type) (b : Type) | m where ix : a -> Traversal' {p} m b Wander p => Index p (Maybe a) () a where - ix {a} () = wander $ traverse {f=f1} {t=Maybe} + ix () = traversed (Wander p, Ord k) => Index p (SortedMap k v) k v where -- magical f1 From 674c79d800c4afd740366cf2be3312ce4d461029 Mon Sep 17 00:00:00 2001 From: Alex Gryzlov Date: Mon, 22 Jul 2019 18:40:22 +0300 Subject: [PATCH 012/126] refactor, add grates --- profunctors.ipkg | 3 + src/Data/Const.idr | 15 +++ src/Data/Profunctor.idr | 119 ++---------------------- src/Data/Profunctor/Cayley.idr | 2 + src/Data/Profunctor/Choice.idr | 55 +++++++++++ src/Data/Profunctor/Closed.idr | 4 + src/Data/Profunctor/Fold.idr | 1 + src/Data/Profunctor/Grate.idr | 23 +++++ src/Data/Profunctor/Lens.idr | 1 + src/Data/Profunctor/Lens/At.idr | 1 + src/Data/Profunctor/Prism.idr | 1 + src/Data/Profunctor/Strong.idr | 52 +++++++++++ src/Data/Profunctor/Traversal.idr | 1 + src/Data/Profunctor/Traversal/Index.idr | 1 + src/Data/Profunctor/Wander.idr | 24 +++++ 15 files changed, 190 insertions(+), 113 deletions(-) create mode 100644 src/Data/Const.idr create mode 100644 src/Data/Profunctor/Choice.idr create mode 100644 src/Data/Profunctor/Grate.idr create mode 100644 src/Data/Profunctor/Strong.idr create mode 100644 src/Data/Profunctor/Wander.idr diff --git a/profunctors.ipkg b/profunctors.ipkg index 6e80ba8..8963274 100644 --- a/profunctors.ipkg +++ b/profunctors.ipkg @@ -4,14 +4,17 @@ sourcedir = src modules = Data.Profunctor , Data.Profunctor.Cayley + , Data.Profunctor.Choice , Data.Profunctor.Closed , Data.Profunctor.Codensity , Data.Profunctor.Composition , Data.Profunctor.Fold + , Data.Profunctor.Grate , Data.Profunctor.Iso , Data.Profunctor.Lens , Data.Profunctor.Lens.At , Data.Profunctor.Prism + , Data.Profunctor.Strong , Data.Profunctor.Trace , Data.Profunctor.Traversal , Data.Profunctor.Traversal.Index diff --git a/src/Data/Const.idr b/src/Data/Const.idr new file mode 100644 index 0000000..5e51643 --- /dev/null +++ b/src/Data/Const.idr @@ -0,0 +1,15 @@ +module Data.Const + +%default total +%access public export + +record Const (a : Type) (b : Type) where + constructor MkConst + runConst : a + +Functor (Const m) where + map _ (MkConst v) = MkConst v + +Monoid m => Applicative (Const m) where + pure _ = MkConst neutral + (MkConst a) <*> (MkConst b) = MkConst (a <+> b) \ No newline at end of file diff --git a/src/Data/Profunctor.idr b/src/Data/Profunctor.idr index f5a58f8..f833f20 100644 --- a/src/Data/Profunctor.idr +++ b/src/Data/Profunctor.idr @@ -5,19 +5,9 @@ import Control.Arrow import Control.Category import Data.Morphisms +%default total %access public export -record Const (a : Type) (b : Type) where - constructor MkConst - runConst : a - -Functor (Const m) where - map _ (MkConst v) = MkConst v - -Monoid m => Applicative (Const m) where - pure _ = MkConst neutral - (MkConst a) <*> (MkConst b) = MkConst (a <+> b) - ||| Profunctors ||| @p The action of the Profunctor on pairs of objects interface Profunctor (p : Type -> Type -> Type) where @@ -174,107 +164,10 @@ implementation Foldable (Forgotten r a) where implementation Traversable (Forgotten r a) where traverse = const $ pure . Forget . runForget --- }}} --- Strong --- {{{ - -||| Generalized UpStar of a Strong Functor -interface Profunctor p => Strong (p : Type -> Type -> Type) where - ||| Create a new Profunctor of tuples with first element from the original - ||| - ||| ````idris example - ||| first' (Kleisli $ \x => Just $ reverse x) - ||| ```` - ||| - first' : p a b -> p (a, c) (b, c) - first' = dimap (\x => (snd x, fst x)) (\x => (snd x, fst x)) . second' - - ||| Create a new Profunctor of tuples with second element from the original - ||| - ||| ````idris example - ||| second' (Kleisli $ \x => Just $ reverse x) - ||| ```` - ||| - second' : p a b -> p (c, a) (c, b) - second' = dimap (\x => (snd x, fst x)) (\x => (snd x, fst x)) . first' - -implementation Monad m => Strong (Kleislimorphism m) where - first' (Kleisli f) = Kleisli $ \ac => f (fst ac) >>= \b => pure (b, snd ac) - second' (Kleisli f) = Kleisli $ \ca => f (snd ca) >>= pure . MkPair (fst ca) - -implementation Strong Morphism where - first' (Mor f) = Mor $ \(a,c) => (f a, c) - second' (Mor f) = Mor $ \(c,a) => (c, f a) - -implementation Functor m => Strong (UpStarred m) where - first' (UpStar f) = UpStar $ \ac => map (\b' => (b', snd ac)) . f $ fst ac - second' (UpStar f) = UpStar $ \ca => map (MkPair $ fst ca) . f $ snd ca - -implementation Arrow p => Strong (WrappedArrow p) where - first' = WrapArrow . first . unwrapArrow - second' = WrapArrow . second . unwrapArrow - -implementation Strong (Forgotten r) where - first' (Forget k) = Forget $ k . fst - second' (Forget k) = Forget $ k . snd - --- }}} --- Choice --- {{{ - -||| Generalized DownStar of a Costrong Functor -interface Profunctor p => Choice (p : Type -> Type -> Type) where - ||| Like first' but with sum rather than product types - ||| - ||| ````idris example - ||| left' (Kleisli $ \x => Just $ reverse x) - ||| ```` - ||| - left' : p a b -> p (Either a c) (Either b c) - left' = dimap mirror mirror . right' - - ||| Like second' but with sum rather than product types - ||| - ||| ````idris example - ||| right' (Kleisli $ \x => Just $ reverse x) - ||| ```` - ||| - right' : p a b -> p (Either c a) (Either c b) - right' = dimap mirror mirror . left' - -implementation Monad m => Choice (Kleislimorphism m) where - left' f = Kleisli $ either (applyKleisli $ f >>> arrow Left) - (applyKleisli $ arrow id >>> arrow Right) - right' f = Kleisli $ either (applyKleisli {f=m} $ arrow id >>> arrow Left) - (applyKleisli $ f >>> arrow Right) - -implementation Choice Morphism where - left' (Mor f) = Mor $ either (Left . f) Right - right' (Mor f) = Mor $ either Left (Right . f) - -implementation Choice Tagged where - left' = Tag . Left . runTagged - right' = Tag . Right . runTagged - -implementation Applicative f => Choice (UpStarred f) where - left' (UpStar f) = UpStar $ either (map Left . f ) (map Right . pure) - right' (UpStar f) = UpStar $ either (map Left . pure) (map Right . f ) - -implementation Monoid r => Choice (Forgotten r) where - left' (Forget k) = Forget . either k $ const neutral - right' (Forget k) = Forget . flip either k $ const neutral - -||| Profunctors that support polymorphic traversals -interface (Strong p, Choice p) => Wander (p : Type -> Type -> Type) where - wander : ({f : Type -> Type} -> Applicative f => (a -> f b) -> s -> f t) -> p a b -> p s t - -Wander Morphism where - wander t (Mor f) = Mor $ runIdentity . t (%implementation) (Id . f) - -Applicative f => Wander (UpStarred f) where - wander @{ap} t (UpStar f) = UpStar $ t ap f - -Monoid r => Wander (Forgotten r) where - wander t (Forget r) = Forget $ runConst . t (%implementation) (MkConst . r) +record Zipping a b where + constructor MkZipping + runZipping : a -> a -> b +Profunctor Zipping where + dimap f g (MkZipping h) = MkZipping $ \a1, a2 => g $ h (f a1) (f a2) -- }}} diff --git a/src/Data/Profunctor/Cayley.idr b/src/Data/Profunctor/Cayley.idr index 432703c..b814b53 100644 --- a/src/Data/Profunctor/Cayley.idr +++ b/src/Data/Profunctor/Cayley.idr @@ -3,6 +3,8 @@ module Data.Profunctor.Cayley import Control.Arrow import Control.Category import Data.Profunctor +import Data.Profunctor.Strong +import Data.Profunctor.Choice import Data.Profunctor.Unsafe %access public export diff --git a/src/Data/Profunctor/Choice.idr b/src/Data/Profunctor/Choice.idr new file mode 100644 index 0000000..3195a56 --- /dev/null +++ b/src/Data/Profunctor/Choice.idr @@ -0,0 +1,55 @@ +module Data.Profunctor.Choice + +import Data.Profunctor +import Control.Category +import Control.Arrow +import Data.Morphisms + +%default total +%access public export + +-- }}} +-- Choice +-- {{{ + +||| Generalized DownStar of a Costrong Functor +interface Profunctor p => Choice (p : Type -> Type -> Type) where + ||| Like first' but with sum rather than product types + ||| + ||| ````idris example + ||| left' (Kleisli $ \x => Just $ reverse x) + ||| ```` + ||| + left' : p a b -> p (Either a c) (Either b c) + left' = dimap mirror mirror . right' + + ||| Like second' but with sum rather than product types + ||| + ||| ````idris example + ||| right' (Kleisli $ \x => Just $ reverse x) + ||| ```` + ||| + right' : p a b -> p (Either c a) (Either c b) + right' = dimap mirror mirror . left' + +implementation Monad m => Choice (Kleislimorphism m) where + left' f = Kleisli $ either (applyKleisli $ f >>> arrow Left) + (applyKleisli $ arrow id >>> arrow Right) + right' f = Kleisli $ either (applyKleisli {f=m} $ arrow id >>> arrow Left) + (applyKleisli $ f >>> arrow Right) + +implementation Choice Morphism where + left' (Mor f) = Mor $ either (Left . f) Right + right' (Mor f) = Mor $ either Left (Right . f) + +implementation Choice Tagged where + left' = Tag . Left . runTagged + right' = Tag . Right . runTagged + +implementation Applicative f => Choice (UpStarred f) where + left' (UpStar f) = UpStar $ either (map Left . f ) (map Right . pure) + right' (UpStar f) = UpStar $ either (map Left . pure) (map Right . f ) + +implementation Monoid r => Choice (Forgotten r) where + left' (Forget k) = Forget . either k $ const neutral + right' (Forget k) = Forget . flip either k $ const neutral \ No newline at end of file diff --git a/src/Data/Profunctor/Closed.idr b/src/Data/Profunctor/Closed.idr index 824655e..8316bb3 100644 --- a/src/Data/Profunctor/Closed.idr +++ b/src/Data/Profunctor/Closed.idr @@ -4,6 +4,7 @@ import Control.Arrow import Control.Category import Data.Morphisms import Data.Profunctor +import Data.Profunctor.Strong import Data.Profunctor.Unsafe %access public export @@ -27,6 +28,9 @@ implementation Functor f => Closed (DownStarred f) where implementation Monoid r => Closed (Forgotten r) where closed = const . Forget $ const neutral +Closed Zipping where + closed (MkZipping f) = MkZipping $ \f1, f2, x => f (f1 x) (f2 x) + ||| Closure adjoins a Closed structure to any Profunctor record Closure (p : Type -> Type -> Type) a b where ||| Adjoin a closed-structured Profunctor to a profunctor diff --git a/src/Data/Profunctor/Fold.idr b/src/Data/Profunctor/Fold.idr index ee54dbf..7559448 100644 --- a/src/Data/Profunctor/Fold.idr +++ b/src/Data/Profunctor/Fold.idr @@ -2,6 +2,7 @@ module Data.Profunctor.Fold import Control.Algebra import Data.Profunctor +import Data.Profunctor.Choice import Data.Profunctor.Prism import Data.SortedSet diff --git a/src/Data/Profunctor/Grate.idr b/src/Data/Profunctor/Grate.idr new file mode 100644 index 0000000..6fc07fe --- /dev/null +++ b/src/Data/Profunctor/Grate.idr @@ -0,0 +1,23 @@ +module Data.Profunctor.Grate + +import Data.Morphisms +import Data.Profunctor +import Data.Profunctor.Closed +import Data.Profunctor.Iso + +%access public export + +Grate : Closed p => Type -> Type -> Type -> Type -> Type +Grate {p} = preIso {p} + +Grate' : Closed p => Type -> Type -> Type +Grate' {p} = Simple $ Grate {p} + +grate : (((s -> a) -> b) -> t) -> Grate {p=Morphism} s t a b +grate f pab = dimap (flip apply) f (closed pab) + +zipWithOf : Grate {p=Zipping} s t a b -> (a -> a -> b) -> s -> s -> t +zipWithOf gr = runZipping . gr . MkZipping + +zipFWithOf : Functor f => Grate {p=DownStarred f} s t a b -> (f a -> b) -> (f s -> t) +zipFWithOf gr = runDownStar . gr . DownStar \ No newline at end of file diff --git a/src/Data/Profunctor/Lens.idr b/src/Data/Profunctor/Lens.idr index 2c59b6b..9319364 100644 --- a/src/Data/Profunctor/Lens.idr +++ b/src/Data/Profunctor/Lens.idr @@ -4,6 +4,7 @@ import Data.Fin import Data.HVect import Data.Morphisms import Data.Profunctor +import Data.Profunctor.Strong import Data.Profunctor.Iso import Data.Vect diff --git a/src/Data/Profunctor/Lens/At.idr b/src/Data/Profunctor/Lens/At.idr index 282af70..3a8c1ad 100644 --- a/src/Data/Profunctor/Lens/At.idr +++ b/src/Data/Profunctor/Lens/At.idr @@ -4,6 +4,7 @@ import Data.Morphisms import Data.SortedMap import Data.SortedSet import Data.Profunctor +import Data.Profunctor.Wander import Data.Profunctor.Lens import Data.Profunctor.Traversal.Index diff --git a/src/Data/Profunctor/Prism.idr b/src/Data/Profunctor/Prism.idr index df590d4..6352203 100644 --- a/src/Data/Profunctor/Prism.idr +++ b/src/Data/Profunctor/Prism.idr @@ -2,6 +2,7 @@ module Data.Profunctor.Prism import Data.Morphisms import Data.Profunctor +import Data.Profunctor.Choice import Data.Profunctor.Iso %access public export diff --git a/src/Data/Profunctor/Strong.idr b/src/Data/Profunctor/Strong.idr new file mode 100644 index 0000000..9328227 --- /dev/null +++ b/src/Data/Profunctor/Strong.idr @@ -0,0 +1,52 @@ +module Data.Profunctor.Strong + +import Data.Profunctor +import Data.Morphisms +import Control.Arrow + +%default total +%access public export + +-- }}} +-- Strong +-- {{{ + +||| Generalized UpStar of a Strong Functor +interface Profunctor p => Strong (p : Type -> Type -> Type) where + ||| Create a new Profunctor of tuples with first element from the original + ||| + ||| ````idris example + ||| first' (Kleisli $ \x => Just $ reverse x) + ||| ```` + ||| + first' : p a b -> p (a, c) (b, c) + first' = dimap (\x => (snd x, fst x)) (\x => (snd x, fst x)) . second' + + ||| Create a new Profunctor of tuples with second element from the original + ||| + ||| ````idris example + ||| second' (Kleisli $ \x => Just $ reverse x) + ||| ```` + ||| + second' : p a b -> p (c, a) (c, b) + second' = dimap (\x => (snd x, fst x)) (\x => (snd x, fst x)) . first' + +implementation Monad m => Strong (Kleislimorphism m) where + first' (Kleisli f) = Kleisli $ \ac => f (fst ac) >>= \b => pure (b, snd ac) + second' (Kleisli f) = Kleisli $ \ca => f (snd ca) >>= pure . MkPair (fst ca) + +implementation Strong Morphism where + first' (Mor f) = Mor $ \(a,c) => (f a, c) + second' (Mor f) = Mor $ \(c,a) => (c, f a) + +implementation Functor m => Strong (UpStarred m) where + first' (UpStar f) = UpStar $ \ac => map (\b' => (b', snd ac)) . f $ fst ac + second' (UpStar f) = UpStar $ \ca => map (MkPair $ fst ca) . f $ snd ca + +implementation Arrow p => Strong (WrappedArrow p) where + first' = WrapArrow . first . unwrapArrow + second' = WrapArrow . second . unwrapArrow + +implementation Strong (Forgotten r) where + first' (Forget k) = Forget $ k . fst + second' (Forget k) = Forget $ k . snd \ No newline at end of file diff --git a/src/Data/Profunctor/Traversal.idr b/src/Data/Profunctor/Traversal.idr index 17c084d..25d4aff 100644 --- a/src/Data/Profunctor/Traversal.idr +++ b/src/Data/Profunctor/Traversal.idr @@ -1,6 +1,7 @@ module Data.Profunctor.Fold import Data.Profunctor +import Data.Profunctor.Wander import Data.Profunctor.Iso import Data.Morphisms import Data.Bitraversable diff --git a/src/Data/Profunctor/Traversal/Index.idr b/src/Data/Profunctor/Traversal/Index.idr index 2bfcc26..049cee7 100644 --- a/src/Data/Profunctor/Traversal/Index.idr +++ b/src/Data/Profunctor/Traversal/Index.idr @@ -3,6 +3,7 @@ module Data.Profunctor.Traversal.Index import Data.SortedMap import Data.SortedSet import Data.Profunctor +import Data.Profunctor.Wander import Data.Profunctor.Traversal %default total diff --git a/src/Data/Profunctor/Wander.idr b/src/Data/Profunctor/Wander.idr new file mode 100644 index 0000000..cbc960f --- /dev/null +++ b/src/Data/Profunctor/Wander.idr @@ -0,0 +1,24 @@ +module Data.Profunctor.Wander + +import Control.Monad.Identity +import Data.Const +import Data.Profunctor +import Data.Profunctor.Strong +import Data.Profunctor.Choice +import Data.Morphisms + +%default total +%access public export + +||| Profunctors that support polymorphic traversals +interface (Strong p, Choice p) => Wander (p : Type -> Type -> Type) where + wander : ({f : Type -> Type} -> Applicative f => (a -> f b) -> s -> f t) -> p a b -> p s t + +Wander Morphism where + wander t (Mor f) = Mor $ runIdentity . t (%implementation) (Id . f) + +Applicative f => Wander (UpStarred f) where + wander @{ap} t (UpStar f) = UpStar $ t ap f + +Monoid r => Wander (Forgotten r) where + wander t (Forget r) = Forget $ runConst . t (%implementation) (MkConst . r) From 9844509f7d57d710e341406b90b54ebb3da1791e Mon Sep 17 00:00:00 2001 From: Alex Gryzlov Date: Mon, 22 Jul 2019 19:52:52 +0300 Subject: [PATCH 013/126] instances --- src/Data/Const.idr | 11 +++++++++-- src/Data/Profunctor.idr | 4 ++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/Data/Const.idr b/src/Data/Const.idr index 5e51643..8b8a1cd 100644 --- a/src/Data/Const.idr +++ b/src/Data/Const.idr @@ -3,7 +3,7 @@ module Data.Const %default total %access public export -record Const (a : Type) (b : Type) where +record Const a b where constructor MkConst runConst : a @@ -12,4 +12,11 @@ Functor (Const m) where Monoid m => Applicative (Const m) where pure _ = MkConst neutral - (MkConst a) <*> (MkConst b) = MkConst (a <+> b) \ No newline at end of file + (MkConst a) <*> (MkConst b) = MkConst (a <+> b) + +Foldable (Const a) where + foldr _ x _ = x + foldl _ x _ = x + +Traversable (Const a) where + traverse _ (MkConst x) = pure $ MkConst x \ No newline at end of file diff --git a/src/Data/Profunctor.idr b/src/Data/Profunctor.idr index f833f20..2a29300 100644 --- a/src/Data/Profunctor.idr +++ b/src/Data/Profunctor.idr @@ -79,6 +79,10 @@ implementation Applicative f => Applicative (UpStarred f a) where pure = UpStar . const . pure (UpStar ff) <*> (UpStar fx) = UpStar $ \a => ff a <*> fx a +Alternative f => Alternative (UpStarred f a) where + empty = UpStar $ const empty + (UpStar fa) <|> (UpStar fb) = UpStar $ \x => (fa x) <|> (fb x) + implementation Monad f => Monad (UpStarred f a) where (UpStar m) >>= f = UpStar $ \e => m e >>= flip runUpStar e . f From c186ce680187e7127dbf186299323438fb5d4532 Mon Sep 17 00:00:00 2001 From: Alex Gryzlov Date: Tue, 23 Jul 2019 00:20:53 +0300 Subject: [PATCH 014/126] getter --- src/Data/Profunctor/Lens.idr | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/Data/Profunctor/Lens.idr b/src/Data/Profunctor/Lens.idr index 9319364..603fa15 100644 --- a/src/Data/Profunctor/Lens.idr +++ b/src/Data/Profunctor/Lens.idr @@ -40,24 +40,30 @@ lens' f = lmap f . strength lens : Lensing p => (s -> a) -> (s -> b -> t) -> Lens {p} s t a b lens gt st = lens' $ \s => (\b => st s b, gt s) -||| Build a function to look at stuff from a Lens -view : Lens {p=Forgotten a} s t a b -> s -> a -view = runForget . (\f => f $ Forget id) - foldMapOf : Lens {p=Forgotten r} s t a b -> (a -> r) -> s -> r foldMapOf l f = runForget $ l $ Forget f +foldrOf : Lens {p=Forgotten (Endomorphism r)} s t a b -> (a -> r -> r) -> r -> s -> r +foldrOf p f = flip $ applyEndo . foldMapOf p (Endo . f) + +Getter : Type -> Type -> Type -> Type -> Type +Getter s t a = Lens {p=Forgotten a} s t a + +||| Build a function to look at stuff from a Lens +view : Getter s t a b -> s -> a +view = runForget . (\f => f $ Forget id) + ||| Create a getter from arbitrary function `s -> a`. -getter : (s -> a) -> Lens {p=Forgotten a} s t a b -getter k = \(Forget aa) => Forget $ aa . k +getter : (s -> a) -> Getter s t a b +getter k (Forget aa) = Forget $ aa . k ||| Combine two getters. -takeBoth : Lens {p=Forgotten a} s t a b -> Lens {p=Forgotten c} s t c d -> Lens {p=Forgotten (a, c)} s t (a, c) (b, d) +takeBoth : Getter s t a b -> Getter s t c d -> Getter s t (a, c) (b, d) takeBoth l r = getter $ \s => (view l s, view r s) infixl 8 ^. ||| Infix synonym for `view` -(^.) : s -> Lens {p=Forgotten a} s t a b -> a +(^.) : s -> Getter s t a b -> a (^.) = flip view infixl 8 ^? @@ -74,7 +80,7 @@ infixr 4 &~ (&~) = over sets : ((a -> b) -> s -> t) -> Lens {p=Morphism} s t a b -sets l = \(Mor f) => Mor $ l f +sets l (Mor f) = Mor $ l f ||| Set something to a specific value with a Lens set : Lens {p=Morphism} s t a b -> b -> s -> t From c7f08c997fa093cf98dbfb1c2b7ca451cb7201c4 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 23 May 2022 22:46:08 +0200 Subject: [PATCH 015/126] Update export statement syntax --- src/Data/Const.idr | 8 +++- src/Data/Profunctor.idr | 33 ++++++++++++-- src/Data/Profunctor/Cayley.idr | 13 +++++- src/Data/Profunctor/Choice.idr | 9 +++- src/Data/Profunctor/Closed.idr | 19 +++++++-- src/Data/Profunctor/Codensity.idr | 5 ++- src/Data/Profunctor/Comonad.idr | 15 ++++++- src/Data/Profunctor/Composition.idr | 9 +++- src/Data/Profunctor/Fold.idr | 57 ++++++++++++++++++++++++- src/Data/Profunctor/Grate.idr | 9 ++-- src/Data/Profunctor/Iso.idr | 23 +++++++++- src/Data/Profunctor/Lens.idr | 36 +++++++++++++++- src/Data/Profunctor/Lens/At.idr | 6 ++- src/Data/Profunctor/Prism.idr | 26 ++++++++++- src/Data/Profunctor/Ran.idr | 6 ++- src/Data/Profunctor/Strong.idr | 9 +++- src/Data/Profunctor/Trace.idr | 3 +- src/Data/Profunctor/Traversal.idr | 7 ++- src/Data/Profunctor/Traversal/Index.idr | 7 ++- src/Data/Profunctor/Unsafe.idr | 6 ++- src/Data/Profunctor/Wander.idr | 5 ++- src/Data/Verified/Profunctor.idr | 3 +- 22 files changed, 270 insertions(+), 44 deletions(-) diff --git a/src/Data/Const.idr b/src/Data/Const.idr index 8b8a1cd..03817d3 100644 --- a/src/Data/Const.idr +++ b/src/Data/Const.idr @@ -1,22 +1,26 @@ module Data.Const %default total -%access public export +public export record Const a b where constructor MkConst runConst : a +export Functor (Const m) where map _ (MkConst v) = MkConst v +export Monoid m => Applicative (Const m) where pure _ = MkConst neutral (MkConst a) <*> (MkConst b) = MkConst (a <+> b) +export Foldable (Const a) where foldr _ x _ = x foldl _ x _ = x +export Traversable (Const a) where - traverse _ (MkConst x) = pure $ MkConst x \ No newline at end of file + traverse _ (MkConst x) = pure $ MkConst x diff --git a/src/Data/Profunctor.idr b/src/Data/Profunctor.idr index 2a29300..db33aaf 100644 --- a/src/Data/Profunctor.idr +++ b/src/Data/Profunctor.idr @@ -6,10 +6,10 @@ import Control.Category import Data.Morphisms %default total -%access public export ||| Profunctors ||| @p The action of the Profunctor on pairs of objects +public export interface Profunctor (p : Type -> Type -> Type) where ||| Map over both arguments ||| @@ -38,21 +38,26 @@ interface Profunctor (p : Type -> Type -> Type) where rmap : (a -> b) -> p c a -> p c b rmap = dimap id +export implementation Monad m => Profunctor (Kleislimorphism m) where dimap f g (Kleisli h) = Kleisli $ \a => liftA g $ h $ f a +export implementation Profunctor Morphism where dimap f g (Mor h) = Mor $ g . h . f ||| A method of attaching a phantom type as a "tag" +public export record Tagged a b where constructor Tag runTagged : b +export implementation Profunctor Tagged where lmap = const $ Tag . runTagged rmap f = Tag . f . runTagged +export implementation Functor (Tagged a) where map = rmap @@ -65,24 +70,30 @@ implementation Functor (Tagged a) where ||| UpStar $ \x => Just $ isDigit x ||| ```` ||| +public export record UpStarred (f : Type -> Type) d c where constructor UpStar runUpStar : d -> f c +export implementation Functor f => Profunctor (UpStarred f) where dimap ab cd (UpStar bfc) = UpStar $ \a => map cd $ bfc $ ab a +export implementation Functor f => Functor (UpStarred f a) where map = rmap +export implementation Applicative f => Applicative (UpStarred f a) where pure = UpStar . const . pure (UpStar ff) <*> (UpStar fx) = UpStar $ \a => ff a <*> fx a -Alternative f => Alternative (UpStarred f a) where +export +implementation Alternative f => Alternative (UpStarred f a) where empty = UpStar $ const empty (UpStar fa) <|> (UpStar fb) = UpStar $ \x => (fa x) <|> (fb x) +export implementation Monad f => Monad (UpStarred f a) where (UpStar m) >>= f = UpStar $ \e => m e >>= flip runUpStar e . f @@ -96,20 +107,25 @@ implementation Monad f => Monad (UpStarred f a) where ||| DownStar $ show ||| ```` ||| +public export record DownStarred (f : Type -> Type) d c where constructor DownStar runDownStar : f d -> c +export implementation Functor f => Profunctor (DownStarred f) where dimap ab cd (DownStar fbc) = DownStar $ cd . fbc . map ab +export implementation Functor (DownStarred f a) where map = (DownStar .) . (. runDownStar) . (.) +export implementation Applicative (DownStarred f a) where pure = DownStar . const (DownStar ff) <*> (DownStar fx) = DownStar $ \a => ff a $ fx a +export implementation Monad (DownStarred f a) where (DownStar m) >>= f = DownStar $ \x => runDownStar (f $ m x) x @@ -123,14 +139,17 @@ implementation Monad (DownStarred f a) where ||| WrapArrow $ arrow ((+) 1) ||| ```` ||| +public export record WrappedArrow (p : Type -> Type -> Type) a b where constructor WrapArrow unwrapArrow : p a b +export implementation Category p => Category (WrappedArrow p) where (WrapArrow f) . (WrapArrow g) = WrapArrow $ f . g id = WrapArrow id +export implementation Arrow p => Arrow (WrappedArrow p) where arrow = WrapArrow . arrow first = WrapArrow . first . unwrapArrow @@ -138,6 +157,7 @@ implementation Arrow p => Arrow (WrappedArrow p) where (WrapArrow a) *** (WrapArrow b) = WrapArrow $ a *** b (WrapArrow a) &&& (WrapArrow b) = WrapArrow $ a &&& b +export implementation Arrow p => Profunctor (WrappedArrow p) where lmap = (>>>) . arrow rmap = (.) . arrow @@ -152,26 +172,33 @@ implementation Arrow p => Profunctor (WrappedArrow p) where ||| Forget ((+) 1) ||| ```` ||| +public export record Forgotten r a b where constructor Forget runForget : a -> r +export implementation Profunctor (Forgotten r) where dimap f _ (Forget k) = Forget $ k . f +export implementation Functor (Forgotten r a) where map = const $ Forget . runForget +export implementation Foldable (Forgotten r a) where foldr = const const +export implementation Traversable (Forgotten r a) where traverse = const $ pure . Forget . runForget +public export record Zipping a b where constructor MkZipping runZipping : a -> a -> b -Profunctor Zipping where +export +implementation Profunctor Zipping where dimap f g (MkZipping h) = MkZipping $ \a1, a2 => g $ h (f a1) (f a2) -- }}} diff --git a/src/Data/Profunctor/Cayley.idr b/src/Data/Profunctor/Cayley.idr index b814b53..3c1c1c1 100644 --- a/src/Data/Profunctor/Cayley.idr +++ b/src/Data/Profunctor/Cayley.idr @@ -7,9 +7,8 @@ import Data.Profunctor.Strong import Data.Profunctor.Choice import Data.Profunctor.Unsafe -%access public export - ||| Converts Monads on standard types to Monads on Profunctors +public export record Cayleyed (f : Type -> Type) (p : Type -> Type -> Type) a b where ||| ````idris example ||| Cayley $ Just $ Kleisli $ \x => Just $ reverse x @@ -17,28 +16,34 @@ record Cayleyed (f : Type -> Type) (p : Type -> Type -> Type) a b where constructor Cayley runCayley : f (p a b) +export implementation (Functor f, Profunctor p) => Profunctor (Cayleyed f p) where dimap f g = Cayley . map (dimap f g) . runCayley lmap f = Cayley . map (lmap f ) . runCayley rmap g = Cayley . map (rmap g) . runCayley +export implementation (UnsafeProfunctor p, Functor f) => UnsafeProfunctor (Cayleyed f p) where w #. (Cayley p) = Cayley $ map (w #.) p (Cayley p) .# w = Cayley $ map (.# w) p +export implementation (Functor f, Strong p) => Strong (Cayleyed f p) where first' = Cayley . map first' . runCayley second' = Cayley . map second' . runCayley +export implementation (Functor f, Choice p) => Choice (Cayleyed f p) where left' = Cayley . map left' . runCayley right' = Cayley . map right' . runCayley +export implementation (Applicative f, Category p) => Category (Cayleyed f p) where id = Cayley $ pure id (Cayley fpbc) . (Cayley fpab) = Cayley $ liftA2 (.) fpbc fpab +export implementation (Applicative f, Arrow p) => Arrow (Cayleyed f p) where arrow = Cayley . pure . arrow first = Cayley . map first . runCayley @@ -46,17 +51,21 @@ implementation (Applicative f, Arrow p) => Arrow (Cayleyed f p) where (Cayley ab) *** (Cayley cd) = Cayley $ liftA2 (***) ab cd (Cayley ab) &&& (Cayley ac) = Cayley $ liftA2 (&&&) ab ac +export implementation (Applicative f, ArrowChoice p) => ArrowChoice (Cayleyed f p) where left = Cayley . map left . runCayley right = Cayley . map right . runCayley (Cayley ab) +++ (Cayley cd) = Cayley $ liftA2 (+++) ab cd (Cayley ac) \|/ (Cayley bc) = Cayley $ liftA2 (\|/) ac bc +export implementation (Applicative f, ArrowLoop p) => ArrowLoop (Cayleyed f p) where loop = Cayley . map loop . runCayley +export implementation (Applicative f, ArrowZero p) => ArrowZero (Cayleyed f p) where zeroArrow = Cayley $ pure zeroArrow +export implementation (Applicative f, ArrowPlus p) => ArrowPlus (Cayleyed f p) where (Cayley f) <++> (Cayley g) = Cayley $ liftA2 (<++>) f g diff --git a/src/Data/Profunctor/Choice.idr b/src/Data/Profunctor/Choice.idr index 3195a56..0f4c070 100644 --- a/src/Data/Profunctor/Choice.idr +++ b/src/Data/Profunctor/Choice.idr @@ -6,13 +6,13 @@ import Control.Arrow import Data.Morphisms %default total -%access public export -- }}} -- Choice -- {{{ ||| Generalized DownStar of a Costrong Functor +public export interface Profunctor p => Choice (p : Type -> Type -> Type) where ||| Like first' but with sum rather than product types ||| @@ -32,24 +32,29 @@ interface Profunctor p => Choice (p : Type -> Type -> Type) where right' : p a b -> p (Either c a) (Either c b) right' = dimap mirror mirror . left' +export implementation Monad m => Choice (Kleislimorphism m) where left' f = Kleisli $ either (applyKleisli $ f >>> arrow Left) (applyKleisli $ arrow id >>> arrow Right) right' f = Kleisli $ either (applyKleisli {f=m} $ arrow id >>> arrow Left) (applyKleisli $ f >>> arrow Right) +export implementation Choice Morphism where left' (Mor f) = Mor $ either (Left . f) Right right' (Mor f) = Mor $ either Left (Right . f) +export implementation Choice Tagged where left' = Tag . Left . runTagged right' = Tag . Right . runTagged +export implementation Applicative f => Choice (UpStarred f) where left' (UpStar f) = UpStar $ either (map Left . f ) (map Right . pure) right' (UpStar f) = UpStar $ either (map Left . pure) (map Right . f ) +export implementation Monoid r => Choice (Forgotten r) where left' (Forget k) = Forget . either k $ const neutral - right' (Forget k) = Forget . flip either k $ const neutral \ No newline at end of file + right' (Forget k) = Forget . flip either k $ const neutral diff --git a/src/Data/Profunctor/Closed.idr b/src/Data/Profunctor/Closed.idr index 8316bb3..e0a495b 100644 --- a/src/Data/Profunctor/Closed.idr +++ b/src/Data/Profunctor/Closed.idr @@ -7,9 +7,8 @@ import Data.Profunctor import Data.Profunctor.Strong import Data.Profunctor.Unsafe -%access public export - ||| A Closed Profunctor that allows the closed structure to pass through +public export interface Profunctor p => Closed (p : Type -> Type -> Type) where ||| Pass the closed structure through the Profunctor ||| @@ -19,19 +18,24 @@ interface Profunctor p => Closed (p : Type -> Type -> Type) where ||| closed : {x : _} -> p a b -> p (x -> a) (x -> b) +export implementation Closed Morphism where closed = Mor . (.) . applyMor +export implementation Functor f => Closed (DownStarred f) where closed (DownStar fab) = DownStar $ \fxa,x => fab $ map (\f => f x) fxa +export implementation Monoid r => Closed (Forgotten r) where closed = const . Forget $ const neutral -Closed Zipping where +export +implementation Closed Zipping where closed (MkZipping f) = MkZipping $ \f1, f2, x => f (f1 x) (f2 x) ||| Closure adjoins a Closed structure to any Profunctor +public export record Closure (p : Type -> Type -> Type) a b where ||| Adjoin a closed-structured Profunctor to a profunctor ||| @@ -42,33 +46,41 @@ record Closure (p : Type -> Type -> Type) a b where constructor Close runClosure : p (x -> a) (x -> b) +export hither : (s -> (a,b)) -> (s -> a, s -> b) hither h = (fst . h, snd . h) +export yon : (s -> a, s -> b) -> s -> (a,b) yon h s = (fst h s, snd h s) +export implementation Profunctor p => Profunctor (Closure p) where dimap f g (Close p) = Close $ dimap ((.) f) ((.) g) p lmap f (Close p) = Close $ lmap ((.) f) p rmap g (Close p) = Close $ rmap ((.) g) p +export implementation UnsafeProfunctor p => UnsafeProfunctor (Closure p) where w #. (Close p) = Close $ ((.) w) #. p (Close p) .# w = Close $ p .# ((.) w) +export implementation Strong p => Strong (Closure p) where first' (Close p) = Close $ dimap hither yon $ first' p second' (Close p) = Close $ dimap hither yon $ second' p +export implementation Profunctor p => Functor (Closure p a) where map = rmap +export close : Closed p => {a,b : Type} -> ({a',b' : Type} -> p a' b' -> q a' b') -> p a b -> (Closure q) a b close f p = Close {x=believe_me p} . f $ closed p ||| Environment is left adjoint to Closure +public export data Environment : (Type -> Type -> Type) -> Type -> Type -> Type where ||| Convert a Profunctor to an Environment ||| @@ -78,6 +90,7 @@ data Environment : (Type -> Type -> Type) -> Type -> Type -> Type where ||| Environize : ((z -> y) -> b) -> p x y -> (a -> z -> x) -> Environment p a b +export implementation Profunctor p => Profunctor (Environment p) where dimap f g (Environize l m r) = Environize (g . l) m (r . f) lmap f (Environize l m r) = Environize l m (r . f) diff --git a/src/Data/Profunctor/Codensity.idr b/src/Data/Profunctor/Codensity.idr index 096b204..30d4c5d 100644 --- a/src/Data/Profunctor/Codensity.idr +++ b/src/Data/Profunctor/Codensity.idr @@ -4,17 +4,18 @@ import Control.Category import Data.Profunctor import Data.Profunctor.Composition -%access public export - ||| The right Kan extenstion of a Profunctor +public export record Codense (p : Type -> Type -> Type) a b where constructor Codensity runCodensity : p x a -> p x b +export implementation Profunctor p => Profunctor (Codense p) where dimap ca bd f = Codensity $ rmap bd . runCodensity f . rmap ca lmap ca f = Codensity $ runCodensity f . rmap ca rmap bd f = Codensity $ rmap bd . runCodensity f +export implementation Profunctor p => Functor (Codense p a) where map bd f = Codensity $ rmap bd . runCodensity f diff --git a/src/Data/Profunctor/Comonad.idr b/src/Data/Profunctor/Comonad.idr index 461e431..06fbdf1 100644 --- a/src/Data/Profunctor/Comonad.idr +++ b/src/Data/Profunctor/Comonad.idr @@ -4,8 +4,7 @@ import Control.Arrow import Control.Category import Data.Profunctor -%access public export - +public export interface Functor w => Comonad (w : Type -> Type) where extract : w a -> a @@ -15,46 +14,58 @@ interface Functor w => Comonad (w : Type -> Type) where extend : (w a -> b) -> w a -> w b extend f = map f . duplicate +export implementation Comonad (Tagged a) where duplicate = Tag extract = runTagged infixr 1 =>> +export (=>>) : Comonad w => w a -> (w a -> b) -> w b (=>>) = flip extend infixl 1 <<= +export (<<=) : Comonad w => (w a -> b) -> w a -> w b (<<=) = extend +export wfix : Comonad w => w (w a -> a) -> a wfix w = extract w $ w =>> wfix infixr 1 =<= +export (=<=) : Comonad w => (w b -> c) -> (w a -> b) -> w a -> c f =<= g = f . extend g infixr 1 =>= +export (=>=) : Comonad w => (w a -> b) -> (w b -> c) -> w a -> c f =>= g = g . extend f +public export record Cokleislimorphism (w : Type -> Type) a b where constructor Cokleisli runCokleisli : w a -> b +export implementation Functor w => Profunctor (Cokleislimorphism w) where dimap f g (Cokleisli h) = Cokleisli $ g . h . map f +export implementation Comonad w => Category (Cokleislimorphism w) where id = Cokleisli extract (Cokleisli f) . (Cokleisli g) = Cokleisli $ f =<= g +export implementation Functor (Cokleislimorphism w a) where map f (Cokleisli g) = Cokleisli $ f . g +export implementation Applicative (Cokleislimorphism w a) where pure = Cokleisli . const (Cokleisli f) <*> (Cokleisli a) = Cokleisli $ \w => f w $ a w +export implementation Monad (Cokleislimorphism w a) where (Cokleisli k) >>= f = Cokleisli $ \w => runCokleisli (f $ k w) w diff --git a/src/Data/Profunctor/Composition.idr b/src/Data/Profunctor/Composition.idr index 227843a..fccc38a 100644 --- a/src/Data/Profunctor/Composition.idr +++ b/src/Data/Profunctor/Composition.idr @@ -5,34 +5,39 @@ import Control.Category import Data.Profunctor import Data.Profunctor.Closed -%access public export - ||| The composition of two Profunctors +public export data Procomposed : (Type -> Type -> Type) -> (Type -> Type -> Type) -> Type -> Type -> Type where ||| Compose two Profunctors Procompose : {x,c,d : _} -> p x c -> q d x -> Procomposed p q d c +export procomposed : Category p => Procomposed p p a b -> p a b procomposed (Procompose pxc pdx) = pxc . pdx +export implementation (Profunctor p, Profunctor q) => Profunctor (Procomposed p q) where dimap l r (Procompose f g) = Procompose (rmap r f) (lmap l g) lmap l (Procompose f g) = Procompose f (lmap l g) rmap r (Procompose f g) = Procompose (rmap r f) g +export implementation Profunctor p => Functor (Procomposed p q a) where map k (Procompose f g) = Procompose (rmap k f) g ||| The right Kan lift of one Profunctor along another +public export record Rifted (p : Type -> Type -> Type) (q : Type -> Type -> Type) a b where constructor Rift runRift : p b x -> q a x +export implementation (Profunctor p, Profunctor q) => Profunctor (Rifted p q) where dimap ca bd f = Rift $ lmap ca . runRift f . lmap bd lmap ca f = Rift $ lmap ca . runRift f rmap bd f = Rift $ runRift f . lmap bd +export implementation Profunctor p => Functor (Rifted p q a) where map bd f = Rift $ runRift f . lmap bd diff --git a/src/Data/Profunctor/Fold.idr b/src/Data/Profunctor/Fold.idr index 7559448..ca58133 100644 --- a/src/Data/Profunctor/Fold.idr +++ b/src/Data/Profunctor/Fold.idr @@ -6,30 +6,34 @@ import Data.Profunctor.Choice import Data.Profunctor.Prism import Data.SortedSet -%access public export - ||| A leftwards fold +public export data L a b = MkL (r -> b) (r -> a -> r) r ||| Turn a finalization function, an accumulation function, and an initial value ||| into an `L` +export unfoldL : (s -> (b, a -> s)) -> s -> L a b unfoldL f = MkL (fst . f) (snd . f) ||| Run an `L` on a `Foldable` container +export runL : Foldable t => L a b -> t a -> b runL (MkL k h z) = k . foldl h z ||| Run an `L` on a `Foldable` container, accumulating results +export scanL : L a b -> List a -> List b scanL (MkL k _ z) [] = pure $ k z scanL (MkL k h z) (x::xs) = k (h z x) :: scanL (MkL k h (h z x)) xs +export implementation Profunctor L where dimap f g (MkL k h z) = MkL (g . k) ((. f) . h) z rmap g (MkL k h z) = MkL (g . k) h z lmap f (MkL k h z) = MkL k ((. f) . h) z +export implementation Choice L where left' (MkL {r} k h z) = MkL (\e => case e of Left a => Left $ k a Right b => Right b) @@ -48,69 +52,86 @@ implementation Choice L where step (Left c) _ = Left c step _ (Left c) = Left c +export implementation Prisming L where costrength = rmap (either id id) . right' +export implementation Functor (L a) where map = rmap +export implementation Applicative (L a) where pure b = MkL (const b) (const $ const ()) () (MkL f u y) <*> (MkL a v z) = MkL (uncurry $ (. a) . f) (\(x, y), b => (u x b, v y b)) (y, z) +export implementation Monad (L a) where m >>= f = MkL ((. f) . flip runL) ((. pure) . (++)) [] <*> m +export implementation Semigroup m => Semigroup (L a m) where (<+>) = liftA2 (<+>) +export implementation Monoid m => Monoid (L a m) where neutral = pure neutral +export implementation Group m => Group (L a m) where inverse = map inverse +export implementation AbelianGroup m => AbelianGroup (L a m) where +export implementation Ring m => Ring (L a m) where (<.>) = liftA2 (<.>) +export implementation RingWithUnity m => RingWithUnity (L a m) where unity = pure unity -- The `Field` implementation won't type check, but it should exist +export implementation Num n => Num (L a n) where (+) = liftA2 (+) (*) = liftA2 (*) fromInteger = pure . fromInteger +export implementation Neg n => Neg (L a n) where (-) = liftA2 (-) negate = map negate +export implementation Abs n => Abs (L a n) where abs = map abs ||| An `L` to calculate the size of a `Foldable` container +export length : Num a => L _ a length = MkL id (const . (+ 1)) 0 ||| An `L` which returns `True` if the container is empty, and `False` otherwise +export null : L _ Bool null = MkL id (const $ const False) True ||| An `L` which returns either `Just` an element satisfying a given condition or ||| `Nothing` +export find : (a -> Bool) -> L a (Maybe a) find p = MkL id step Nothing where step x a = case x of Nothing => if p a then Just a else Nothing _ => x ||| An `L` which returns either `Just` the index of a given element or `Nothing` +export index : Nat -> L a (Maybe a) index i = MkL done step (Left 0) where step x = case x of Left j => if i == j then Right else const . Left $ S j @@ -119,12 +140,14 @@ index i = MkL done step (Left 0) where done = either (const Nothing) Just ||| An `L` which returns a `List` containing each unique element in the input +export nub : Eq a => L a (List a) nub = MkL (flip snd []) step ([], id) where step : (List a, List a -> List a) -> a -> (List a, List a -> List a) step (k, r) i = if elem i k then (k, r) else (i :: k, r . (i ::)) ||| A faster `nub` +export fastNub : {a : Type} -> Ord a => L a (List a) fastNub {a} = MkL (flip snd $ the (List a) []) (\(s, r), a => if contains a s then (s, r) @@ -132,6 +155,7 @@ fastNub {a} = MkL (flip snd $ the (List a) []) (the (SortedSet a) empty, id) ||| An `L` which returns a sorted `List` of each element in the input +export sort : Ord a => L a (List a) sort = MkL id (flip $ merge . pure) [] where merge : Ord a => List a -> List a -> List a @@ -141,59 +165,73 @@ sort = MkL id (flip $ merge . pure) [] where else y :: merge (x :: xs) ys ||| Turns a binary function into a lazy `L` +export L1 : (a -> a -> a) -> L a (Lazy (Maybe a)) L1 s = MkL Delay (\m => Just . case m of Just x => s x; _ => id) Nothing ||| Returns the first element of its input, if it exists +export first : L a (Maybe a) first = map Force $ L1 const ||| Returns the last element of its input, if it exists +export last : L a (Maybe a) last = map Force . L1 $ flip const ||| Returns the maximum element of its input, if it exists +export maximum : Ord a => L a (Maybe a) maximum = map Force $ L1 max ||| Returns the minimum element of its input, if it exists +export minimum : Ord a => L a (Maybe a) minimum = map Force $ L1 min ||| Sums the elements of its input +export sum : Num a => L a a sum = MkL id (+) 0 ||| Returns the product of the elements of its input +export product : Num a => L a a product = MkL id (*) 0 ||| Concats the elements of its input +export concat : Monoid a => L a a concat = MkL id (<+>) neutral ||| Concats the elements of its input using binary operation given by the ring +export concatR : RingWithUnity a => L a a concatR = MkL id (<.>) unity ||| A rightwards fold +public export data R a b = MkR (r -> b) (a -> r -> r) r ||| Run an `R` on a `Foldable` container +export runR : Foldable t => R a b -> t a -> b runR (MkR k h z) = k . foldr h z ||| Run an `R` on a `Foldable` container, accumulating results +export scanR : R a b -> List a -> List b scanR (MkR k h z) = map k . scan' where scan' [] = pure z scan' (x::xs) = let l = scan' xs in h x (case l of [] => z; (q::_) => q) :: l +export implementation Profunctor R where dimap f g (MkR k h z) = MkR (g . k) (h . f) z rmap g (MkR k h z) = MkR (g . k) h z lmap f (MkR k h z) = MkR k (h . f) z +export implementation Choice R where left' (MkR {r} k h z) = MkR (\e => case e of Left a => Left $ k a Right b => Right b) @@ -212,54 +250,69 @@ implementation Choice R where step (Left c) _ = Left c step _ (Left c) = Left c +export implementation Prisming R where costrength = rmap (either id id) . right' +export implementation Functor (R a) where map = rmap +export implementation Applicative (R a) where pure b = MkR (const b) (const $ const ()) () (MkR f u y) <*> (MkR a v z) = MkR (uncurry $ (. a) . f) (\b, (x, y) => (u b x, v b y)) (y, z) +export implementation Monad (R a) where m >>= f = MkR ((. f) . flip runR) (::) [] <*> m +export implementation Semigroup m => Semigroup (R a m) where (<+>) = liftA2 (<+>) +export implementation Monoid m => Monoid (R a m) where neutral = pure neutral +export implementation Num n => Num (R a n) where (+) = liftA2 (+) (*) = liftA2 (*) fromInteger = pure . fromInteger +export implementation Neg n => Neg (R a n) where (-) = liftA2 (-) negate = map negate +export implementation Abs n => Abs (R a n) where abs = map abs +export implementation Group m => Group (R a m) where inverse = map inverse +export implementation AbelianGroup m => AbelianGroup (R a m) where +export implementation Ring m => Ring (R a m) where (<.>) = liftA2 (<.>) +export implementation RingWithUnity m => RingWithUnity (R a m) where unity = pure unity ||| Convert an `L` to an `R` +export lr : L a b -> R a b lr (MkL k h z) = MkR k (flip h) z ||| Convert an `R` to an `L` +export rl : R a b -> L a b rl (MkR k h z) = MkL k (flip h) z diff --git a/src/Data/Profunctor/Grate.idr b/src/Data/Profunctor/Grate.idr index 6fc07fe..d06f864 100644 --- a/src/Data/Profunctor/Grate.idr +++ b/src/Data/Profunctor/Grate.idr @@ -5,19 +5,22 @@ import Data.Profunctor import Data.Profunctor.Closed import Data.Profunctor.Iso -%access public export - +public export Grate : Closed p => Type -> Type -> Type -> Type -> Type Grate {p} = preIso {p} +public export Grate' : Closed p => Type -> Type -> Type Grate' {p} = Simple $ Grate {p} +export grate : (((s -> a) -> b) -> t) -> Grate {p=Morphism} s t a b grate f pab = dimap (flip apply) f (closed pab) +export zipWithOf : Grate {p=Zipping} s t a b -> (a -> a -> b) -> s -> s -> t zipWithOf gr = runZipping . gr . MkZipping +export zipFWithOf : Functor f => Grate {p=DownStarred f} s t a b -> (f a -> b) -> (f s -> t) -zipFWithOf gr = runDownStar . gr . DownStar \ No newline at end of file +zipFWithOf gr = runDownStar . gr . DownStar diff --git a/src/Data/Profunctor/Iso.idr b/src/Data/Profunctor/Iso.idr index ea8a93a..d047aef 100644 --- a/src/Data/Profunctor/Iso.idr +++ b/src/Data/Profunctor/Iso.idr @@ -2,10 +2,9 @@ module Data.Profunctor.Iso import Data.Profunctor -%access public export - infixl 1 & +export (&) : a -> (a -> b) -> b a & f = f a @@ -17,85 +16,105 @@ a & f = f a ||| fstStrLens = _1 ||| ```` ||| +public export Simple : (Type -> Type -> Type -> Type -> Type) -> Type -> Type -> Type Simple t s a = t s s a a +public export preIso : {p : Type -> Type -> Type} -> Type -> Type -> Type -> Type -> Type preIso {p} s t a b = p a b -> p s t ||| An isomorphism family. +public export Iso : Profunctor p => Type -> Type -> Type -> Type -> Type Iso {p} = preIso {p} ||| An isomorphism family that does not change types +public export Iso' : Profunctor p => Type -> Type -> Type Iso' {p} = Simple $ Iso {p} ||| Turns a coavariant and contravariant function into an `Iso` +export iso : Profunctor p => (s -> a) -> (b -> t) -> Iso {p} s t a b iso = dimap ||| Builds an `Iso` useful for constructing a `Lens` +export lensIso : Profunctor p => (s -> a) -> (s -> b -> t) -> Iso {p} s t (a, s) (b, s) lensIso gt = iso (\s => (gt s, s)) . uncurry . flip ||| Builds an `Iso` useful for constructing a `Prism` +export prismIso : Profunctor p => (b -> t) -> (s -> Either t a) -> Iso {p} s t (Either t a) (Either t b) prismIso = flip iso . either id . Delay ||| Convert an element of the first half of an iso to the second +export forwards : Profunctor p => Iso {p=Forgotten a} s t a b -> s -> a forwards i = runForget . i $ Forget id ||| Convert an element of the second half of an iso to the first +export backwards : Profunctor p => Iso {p=Tagged} s t a b -> b -> t backwards i = runTagged . i . Tag ||| An `Iso` between a function and it's arguments-flipped version +export flipped : Profunctor p => Iso {p} (a -> b -> c) (d -> e -> f) (b -> a -> c) (e -> d -> f) flipped = iso flip flip ||| An `Iso` between a function and it's curried version +export curried : Profunctor p => Iso {p} ((a, b) -> c) ((d, e) -> f) (a -> b -> c) (d -> e -> f) curried = iso curry uncurry ||| An `Iso` between a function and it's uncurried version +export uncurried : Profunctor p => Iso {p} (a -> b -> c) (d -> e -> f) ((a, b) -> c) ((d, e) -> f) uncurried = iso uncurry curry ||| An `Iso` between a list and its reverse +export reversed : Profunctor p => Iso {p} (List a) (List b) (List a) (List b) reversed = iso reverse reverse ||| An `Iso` between a string and a list of its characters +export packed : Profunctor p => Iso' {p} String (List Char) packed = iso unpack pack ||| An `Iso` between a list of characters and its string +export unpacked : Profunctor p => Iso' {p} (List Char) String unpacked = iso pack unpack ||| An `Iso` between a lazy variable and its strict form +export motivated : Profunctor p => Iso {p} a b (Lazy a) (Lazy b) motivated = iso Delay Force ||| An `Iso` between a strict variable and its lazy form +export unmotivated : Profunctor p => Iso {p} (Lazy a) (Lazy b) a b unmotivated = iso Force Delay ||| An `Iso` between an enumerable value and it's `Nat` representation +export enum : (Profunctor p, Enum a) => Iso' {p} Nat a enum = iso fromNat toNat ||| An `Iso` between a `Nat` and its enumerable representation +export denum : (Profunctor p, Enum a) => Iso' {p} a Nat denum = iso toNat fromNat +export mirrored : Profunctor p => Iso {p} (Either a b) (Either c d) (Either b a) (Either d c) mirrored = iso mirror mirror diff --git a/src/Data/Profunctor/Lens.idr b/src/Data/Profunctor/Lens.idr index 603fa15..06fb988 100644 --- a/src/Data/Profunctor/Lens.idr +++ b/src/Data/Profunctor/Lens.idr @@ -8,146 +8,179 @@ import Data.Profunctor.Strong import Data.Profunctor.Iso import Data.Vect -%access public export ||| A `Strong` `Profunctor` that can be used in a `Lens` +public export interface Strong p => Lensing (p : Type -> Type -> Type) where strength : p a b -> p (b -> t, a) t strength = (rmap $ uncurry id) . second' +export implementation Lensing (Forgotten r) where strength (Forget ar) = Forget $ ar . snd +export implementation Functor f => Lensing (UpStarred f) where strength (UpStar f) = UpStar . uncurry $ (. f) . (<$>) +export implementation Lensing Morphism where strength = Mor . uncurry . flip (.) . applyMor ||| A Lens family, strictly speaking, or a polymorphic lens. +public export Lens : Lensing p => Type -> Type -> Type -> Type -> Type Lens {p} = preIso {p} ||| A Lens family that does not change types +public export Lens' : Lensing p => Type -> Type -> Type Lens' {p} = Simple $ Lens {p} ||| Build a `Lens` out of a function. Note this takes one argument, not two +export lens' : Lensing p => (s -> (b -> t, a)) -> Lens {p} s t a b lens' f = lmap f . strength ||| Build a `Lens` out of getter and setter +export lens : Lensing p => (s -> a) -> (s -> b -> t) -> Lens {p} s t a b lens gt st = lens' $ \s => (\b => st s b, gt s) +export foldMapOf : Lens {p=Forgotten r} s t a b -> (a -> r) -> s -> r foldMapOf l f = runForget $ l $ Forget f +export foldrOf : Lens {p=Forgotten (Endomorphism r)} s t a b -> (a -> r -> r) -> r -> s -> r foldrOf p f = flip $ applyEndo . foldMapOf p (Endo . f) +public export Getter : Type -> Type -> Type -> Type -> Type Getter s t a = Lens {p=Forgotten a} s t a ||| Build a function to look at stuff from a Lens +export view : Getter s t a b -> s -> a view = runForget . (\f => f $ Forget id) ||| Create a getter from arbitrary function `s -> a`. +export getter : (s -> a) -> Getter s t a b getter k (Forget aa) = Forget $ aa . k ||| Combine two getters. +export takeBoth : Getter s t a b -> Getter s t c d -> Getter s t (a, c) (b, d) takeBoth l r = getter $ \s => (view l s, view r s) infixl 8 ^. ||| Infix synonym for `view` +export (^.) : s -> Getter s t a b -> a (^.) = flip view infixl 8 ^? +export (^?) : s -> Lens {p=Forgotten $ Maybe a} s t a b -> Maybe a s ^? l = foldMapOf l Just s ||| Build a function to `map` from a Lens +export over : Lens {p=Morphism} s t a b -> (a -> b) -> s -> t over = (applyMor .) . (. Mor) infixr 4 &~ ||| Infix synonym for `over` +export (&~) : Lens {p=Morphism} s t a b -> (a -> b) -> s -> t (&~) = over +export sets : ((a -> b) -> s -> t) -> Lens {p=Morphism} s t a b sets l (Mor f) = Mor $ l f ||| Set something to a specific value with a Lens +export set : Lens {p=Morphism} s t a b -> b -> s -> t set = (. const) . over infixr 4 .~ ||| Infix synonym for `set` +export (.~) : Lens {p=Morphism} s t a b -> b -> s -> t (.~) = set +export mapped : Functor f => Lens {p=Morphism} (f a) (f b) a b mapped = sets map infixr 4 +~ ||| Increment the target of a lens by a number +export (+~) : Num a => Lens {p=Morphism} s t a a -> a -> s -> t (+~) = (. (+)) . over infixr 4 -~ ||| Decrement the target of a lens by a number +export (-~) : Neg a => Lens {p=Morphism} s t a a -> a -> s -> t (-~) = (. (-)) . over infixr 4 *~ ||| Multiply the target of a lens by a number +export (*~) : Num a => Lens {p=Morphism} s t a a -> a -> s -> t (*~) = (. (*)) . over infixr 4 /~ ||| Divide the target of a lens by a number +export (/~) : Fractional a => Lens {p=Morphism} s t a a -> a -> s -> t (/~) = (. (/)) . over infixr 4 <+>~ ||| Associatively combine the target of a Lens with another value +export (<+>~) : Semigroup a => Lens {p=Morphism} s t a a -> a -> s -> t (<+>~) = (. (<+>)) . over infixr 4 $>~ ||| Rightwards sequence the target of a lens with an applicative +export ($>~) : Applicative f => Lens {p=Morphism} s t (f a) (f a) -> f a -> s -> t ($>~) l = over l . (*>) infixr 4 <$~ ||| Rightwards sequence the target of a lens with an applicative +export (<$~) : Applicative f => Lens {p=Morphism} s t (f a) (f a) -> f a -> s -> t (<$~) l = over l . (<*) ||| A Lens for the first element of a tuple +export _1 : Lensing p => Lens {p} (a, b) (x, b) a x _1 = lens' $ \(a,b) => (flip MkPair b, a) ||| A Lens for the second element of a tuple +export _2 : Lensing p => Lens {p} (b, a) (b, x) a x _2 = lens' $ \(b,a) => (MkPair b, a) ||| A Lens for the first element of a non-empty vector +export _vCons : Lensing p => Lens {p} (Vect (S n) a) (Vect (S n) b) (a, Vect n a) (b, Vect n b) _vCons = lens' $ \(x::xs) => (uncurry (::), (x,xs)) ||| A Lens for the nth element of a big-enough vector +export _vNth : Lensing p => {m : Nat} -> (n : Fin (S m)) -> Lens {p} (Vect (S m) a) (Vect (S m) b) (a, Vect m a) (b, Vect m b) _vNth n = lens' $ \v => (uncurry $ insertAt n, (index n v, deleteAt n v)) ||| A Lens for the nth element of a big-enough heterogenous vector +export _hVNth : Lensing p => (i : Fin (S l)) -> Lens {p} (HVect us) (HVect vs) (index i us, HVect (deleteAt i us)) (index i vs, HVect (deleteAt i vs)) @@ -159,5 +192,6 @@ _hVNth n = lens' $ \v => insertAt' (FS k) y [] = absurd k ||| Everything has a `()` in it +export devoid : Lensing p => Lens' {p} a () devoid = lens' $ flip MkPair () . const diff --git a/src/Data/Profunctor/Lens/At.idr b/src/Data/Profunctor/Lens/At.idr index 3a8c1ad..2549f46 100644 --- a/src/Data/Profunctor/Lens/At.idr +++ b/src/Data/Profunctor/Lens/At.idr @@ -9,18 +9,21 @@ import Data.Profunctor.Lens import Data.Profunctor.Traversal.Index %default total -%access public export ||| Allows adding and deleting elements from "container-like" types +public export interface (Lensing p, Index p m a b) => At (p : Type -> Type -> Type) (m : Type) (a : Type) (b : Type) | m where at : a -> Lens' {p} m (Maybe b) +export (Wander p, Lensing p) => At p (Maybe a) () a where at () = id +export (Wander p, Lensing p, Ord k) => At p (SortedMap k v) k v where at k = lens (lookup k) (\m => maybe (delete k m) (\v => insert k v m)) +export (Wander p, Lensing p, Ord a) => At p (SortedSet a) a () where at x = lens get (flip update) where @@ -28,5 +31,6 @@ interface (Lensing p, Index p m a b) => At (p : Type -> Type -> Type) (m : Type) update Nothing = delete x update (Just _) = insert x +export sans : At Morphism m a b => a -> m -> m sans {m} k = at {p=Morphism} {m} k .~ Nothing diff --git a/src/Data/Profunctor/Prism.idr b/src/Data/Profunctor/Prism.idr index 6352203..099aee8 100644 --- a/src/Data/Profunctor/Prism.idr +++ b/src/Data/Profunctor/Prism.idr @@ -5,99 +5,121 @@ import Data.Profunctor import Data.Profunctor.Choice import Data.Profunctor.Iso -%access public export - ||| A `Choice` `Profunctor` that can be used in a `Prism` +public export interface Choice p => Prisming (p : Type -> Type -> Type) where costrength : p a b -> p (Either b a) b costrength = rmap (either id id) . right' +export implementation Prisming Morphism where costrength = Mor . either id . Delay . applyMor +export implementation Monoid r => Prisming (Forgotten r) where costrength p = Forget . either (const neutral) $ runForget p +export implementation Applicative f => Prisming (UpStarred f) where costrength p = UpStar . either pure $ runUpStar p +export implementation Prisming Tagged where costrength = Tag . runTagged ||| A `Lens` for sum types instead of product types +public export Prism : Prisming p => Type -> Type -> Type -> Type -> Type Prism {p} = preIso {p} ||| A Prism that does not change types +public export Prism' : Prisming p => Type -> Type -> Type Prism' {p} = Simple $ Prism {p} ||| Build a `Prism` from two functions +export prism : Prisming p => (b -> t) -> (s -> Either t a) -> Prism {p} s t a b prism f g = lmap g . costrength . rmap f +export prism' : Prisming p => (b -> s) -> (s -> Maybe a) -> Prism {p} s s a b prism' f g = prism f $ \s => maybe (Left s) Right $ g s +public export record First a where constructor MkFirst runFirst : Maybe a +export implementation Semigroup (First a) where (MkFirst Nothing) <+> r = r l <+> _ = l +export implementation Monoid (First a) where neutral = MkFirst Nothing ||| Build a function from a `Prism` to look at stuff +export preview : Prism {p=Forgotten (First a)} s _ a _ -> s -> Maybe a preview l = runFirst . runForget (l . Forget $ MkFirst . Just) ||| Build a function from a `Prism` to `map` +export review : Prism {p=Tagged} s t a b -> b -> t review = (runTagged .) . (. Tag) ||| A `Prism` for the left half of an `Either` +export _l : Prisming p => Prism {p} (Either a c) (Either b c) a b _l = prism Left $ either Right (Left . Right) ||| A `Prism` for the right half of an `Either` +export _r : Prisming p => Prism {p} (Either c a) (Either c b) a b _r = prism Right $ either (Left . Left) Right ||| A `Prism` for the just case of a `Maybe` +export _j : Prisming p => Prism {p} (Maybe a) (Maybe b) a b _j = prism Just $ maybe (Left Nothing) Right ||| A `Prism` for the nothing case of a `Maybe` +export _n : Prisming p => Prism' {p} (Maybe a) () _n = prism' (const Nothing) . maybe (Just ()) $ const Nothing ||| A `Prism` for the left side of a `List` +export _lCons : Prisming p => Prism {p} (List a) (List b) (a, List a) (b, List b) _lCons = prism (uncurry (::)) $ \aas => case aas of (a::as) => Right (a, as) [] => Left [] ||| A `Prism` for the left side of a `String` +export _strCons : Prisming p => Prism' {p} String (Char, String) _strCons = prism (uncurry strCons) $ \aas => case unpack aas of (a::as) => Right (a, pack as) [] => Left "" ||| A prism for equality +export only : (Eq a, Prisming p) => a -> Prism' {p} a () only a = prism (const a) $ \x => if x == a then Left x else Right () ||| A prism for near-equality, as determined by a given predicate +export nearly : Prisming p => a -> (a -> Bool) -> Prism' {p} a () nearly a p = prism (const a) $ if p a then Left else const $ Right () ||| Checks whether an object would match a given `Prism` +export is : Prism {p=Forgotten (First a)} s _ a _ -> s -> Bool is = (isJust .) . preview ||| Checks whether an object won't match a given `Prism` +export isn't : Prism {p=Forgotten (First a)} s _ a _ -> s -> Bool isn't = (isNothing .) . preview diff --git a/src/Data/Profunctor/Ran.idr b/src/Data/Profunctor/Ran.idr index 02be56b..a0bd87b 100644 --- a/src/Data/Profunctor/Ran.idr +++ b/src/Data/Profunctor/Ran.idr @@ -4,21 +4,23 @@ import Data.Profunctor import Data.Profunctor.Composition import Data.Profunctor.Monad -%access public export - ||| The right Kan extension of a profunctor +public export record Ran : (Type -> Type -> Type) -> (Type -> Type -> Type) -> Type -> Type -> Type where Run : {x : _} -> (runRan : p x a -> q x b) -> Ran p q a b +export implementation (Profunctor p, Profunctor q) => Profunctor (Ran p q) where dimap ca bd f = Run $ rmap bd . runRan f . rmap ca lmap ca f = Run $ runRan f . rmap ca rmap bd f = Run $ rmap bd . runRan f +export implementation Profunctor q => Functor (Ran p q a) where map bd f = Run $ rmap bd . runRan f ||| Split up composed Profunctors by putting a Ran in the middle +export curryRan : (Procomposed p q -/-> r) -> p -/-> Ran q r curryRan f a b p = Run $ \q => f a b $ Procompose p q diff --git a/src/Data/Profunctor/Strong.idr b/src/Data/Profunctor/Strong.idr index 9328227..4ab3e4a 100644 --- a/src/Data/Profunctor/Strong.idr +++ b/src/Data/Profunctor/Strong.idr @@ -5,13 +5,13 @@ import Data.Morphisms import Control.Arrow %default total -%access public export -- }}} -- Strong -- {{{ ||| Generalized UpStar of a Strong Functor +public export interface Profunctor p => Strong (p : Type -> Type -> Type) where ||| Create a new Profunctor of tuples with first element from the original ||| @@ -31,22 +31,27 @@ interface Profunctor p => Strong (p : Type -> Type -> Type) where second' : p a b -> p (c, a) (c, b) second' = dimap (\x => (snd x, fst x)) (\x => (snd x, fst x)) . first' +export implementation Monad m => Strong (Kleislimorphism m) where first' (Kleisli f) = Kleisli $ \ac => f (fst ac) >>= \b => pure (b, snd ac) second' (Kleisli f) = Kleisli $ \ca => f (snd ca) >>= pure . MkPair (fst ca) +export implementation Strong Morphism where first' (Mor f) = Mor $ \(a,c) => (f a, c) second' (Mor f) = Mor $ \(c,a) => (c, f a) +export implementation Functor m => Strong (UpStarred m) where first' (UpStar f) = UpStar $ \ac => map (\b' => (b', snd ac)) . f $ fst ac second' (UpStar f) = UpStar $ \ca => map (MkPair $ fst ca) . f $ snd ca +export implementation Arrow p => Strong (WrappedArrow p) where first' = WrapArrow . first . unwrapArrow second' = WrapArrow . second . unwrapArrow +export implementation Strong (Forgotten r) where first' (Forget k) = Forget $ k . fst - second' (Forget k) = Forget $ k . snd \ No newline at end of file + second' (Forget k) = Forget $ k . snd diff --git a/src/Data/Profunctor/Trace.idr b/src/Data/Profunctor/Trace.idr index aa64e7a..45055f4 100644 --- a/src/Data/Profunctor/Trace.idr +++ b/src/Data/Profunctor/Trace.idr @@ -2,9 +2,8 @@ module Data.Profunctor.Trace import Data.Profunctor -%access public export - ||| Coend of Profunctor +public export record Traced (f : Type -> Type -> Type) where constructor Trace runTrace : f a a diff --git a/src/Data/Profunctor/Traversal.idr b/src/Data/Profunctor/Traversal.idr index 25d4aff..d482cba 100644 --- a/src/Data/Profunctor/Traversal.idr +++ b/src/Data/Profunctor/Traversal.idr @@ -8,17 +8,20 @@ import Data.Bitraversable import Control.Monad.Identity %default total -%access public export +public export Traversal : Wander p => Type -> Type -> Type -> Type -> Type Traversal {p} = preIso {p} ||| A Traversal that does not change types +public export Traversal' : Wander p => Type -> Type -> Type Traversal' {p} = Simple $ Traversal {p} +export traversed : (Wander p, Traversable t) => Traversal {p} (t a) (t b) a b traversed {t} = wander $ traverse {f=f1} {t} +export both : Bitraversable r => Traversal {p=Morphism} (r a a) (r b b) a b -both (Mor f) = Mor $ runIdentity . bitraverse {f=Identity} (Id . f) (Id . f) \ No newline at end of file +both (Mor f) = Mor $ runIdentity . bitraverse {f=Identity} (Id . f) (Id . f) diff --git a/src/Data/Profunctor/Traversal/Index.idr b/src/Data/Profunctor/Traversal/Index.idr index 049cee7..320aebe 100644 --- a/src/Data/Profunctor/Traversal/Index.idr +++ b/src/Data/Profunctor/Traversal/Index.idr @@ -7,18 +7,21 @@ import Data.Profunctor.Wander import Data.Profunctor.Traversal %default total -%access public export +public export interface Wander p => Index (p : Type -> Type -> Type) (m : Type) (a : Type) (b : Type) | m where ix : a -> Traversal' {p} m b +export Wander p => Index p (Maybe a) () a where ix () = traversed +export (Wander p, Ord k) => Index p (SortedMap k v) k v where -- magical f1 ix k = wander $ \coalg, m => maybe (pure {f=f1} m) (map {f=f1} (\v => insert k v m) . coalg) (lookup k m) +export (Wander p, Ord a) => Index p (SortedSet a) a () where -- magical f1 - ix x = wander $ \_ => pure {f=f1} . SortedSet.insert x \ No newline at end of file + ix x = wander $ \_ => pure {f=f1} . SortedSet.insert x diff --git a/src/Data/Profunctor/Unsafe.idr b/src/Data/Profunctor/Unsafe.idr index e55683b..b1df720 100644 --- a/src/Data/Profunctor/Unsafe.idr +++ b/src/Data/Profunctor/Unsafe.idr @@ -3,11 +3,10 @@ module Data.Profunctor.Unsafe import Data.Morphisms import Data.Profunctor -%access public export - infixr 9 #. infixl 8 .# +public export interface Profunctor p => UnsafeProfunctor (p : Type -> Type -> Type) where ||| Map the second argument of a Profunctor covariantly with a function ||| which is assumed to be a cast @@ -19,13 +18,16 @@ interface Profunctor p => UnsafeProfunctor (p : Type -> Type -> Type) where (.#) : p b c -> (a -> b) -> p a c (.#) = flip lmap +export implementation UnsafeProfunctor Morphism where (#.) = const believe_me (.#) = const . believe_me +export implementation Monad m => UnsafeProfunctor (Kleislimorphism m) where (.#) = const . believe_me +export implementation UnsafeProfunctor Tagged where (#.) = const believe_me (.#) = const . Tag . runTagged diff --git a/src/Data/Profunctor/Wander.idr b/src/Data/Profunctor/Wander.idr index cbc960f..a56c2d0 100644 --- a/src/Data/Profunctor/Wander.idr +++ b/src/Data/Profunctor/Wander.idr @@ -8,17 +8,20 @@ import Data.Profunctor.Choice import Data.Morphisms %default total -%access public export ||| Profunctors that support polymorphic traversals +public export interface (Strong p, Choice p) => Wander (p : Type -> Type -> Type) where wander : ({f : Type -> Type} -> Applicative f => (a -> f b) -> s -> f t) -> p a b -> p s t +export Wander Morphism where wander t (Mor f) = Mor $ runIdentity . t (%implementation) (Id . f) +export Applicative f => Wander (UpStarred f) where wander @{ap} t (UpStar f) = UpStar $ t ap f +export Monoid r => Wander (Forgotten r) where wander t (Forget r) = Forget $ runConst . t (%implementation) (MkConst . r) diff --git a/src/Data/Verified/Profunctor.idr b/src/Data/Verified/Profunctor.idr index f36ca2d..6733d53 100644 --- a/src/Data/Verified/Profunctor.idr +++ b/src/Data/Verified/Profunctor.idr @@ -2,10 +2,9 @@ module Data.Verified.Profunctor import Data.Profunctor -%access public export - ||| Verified Profunctors ||| A Profunctor for which identity and composition laws are verified +public export interface Profunctor p => VerifiedProfunctor (p : Type -> Type -> Type) where profunctorIdentity : {a : Type} -> {b : Type} -> (x : p a b) -> dimap Basics.id Basics.id x = x profunctorComposition : {a : Type} -> {b : Type} -> {c : Type} -> From 46381d015e5642a53c1cfbbd2faf0d950433dde9 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 23 May 2022 22:46:57 +0200 Subject: [PATCH 016/126] Quantify Profunctor free type variable --- src/Data/Profunctor.idr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Profunctor.idr b/src/Data/Profunctor.idr index db33aaf..dd8eda1 100644 --- a/src/Data/Profunctor.idr +++ b/src/Data/Profunctor.idr @@ -10,7 +10,7 @@ import Data.Morphisms ||| Profunctors ||| @p The action of the Profunctor on pairs of objects public export -interface Profunctor (p : Type -> Type -> Type) where +interface Profunctor (0 p : Type -> Type -> Type) | p where ||| Map over both arguments ||| ||| ````idris example From a8f3729dbdf3070877ac897b8f2a84a4c1a86a95 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 23 May 2022 22:48:54 +0200 Subject: [PATCH 017/126] Use map function instead of liftA --- src/Data/Profunctor.idr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Profunctor.idr b/src/Data/Profunctor.idr index dd8eda1..90b8d5b 100644 --- a/src/Data/Profunctor.idr +++ b/src/Data/Profunctor.idr @@ -40,7 +40,7 @@ interface Profunctor (0 p : Type -> Type -> Type) | p where export implementation Monad m => Profunctor (Kleislimorphism m) where - dimap f g (Kleisli h) = Kleisli $ \a => liftA g $ h $ f a + dimap f g (Kleisli h) = Kleisli $ map g . h . f export implementation Profunctor Morphism where From 5754348863ed30b4998977e5638c8a02de7cd871 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 23 May 2022 23:15:37 +0200 Subject: [PATCH 018/126] Remove profunctor type variable from determining parameters --- src/Data/Profunctor.idr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Profunctor.idr b/src/Data/Profunctor.idr index 90b8d5b..3461ad3 100644 --- a/src/Data/Profunctor.idr +++ b/src/Data/Profunctor.idr @@ -10,7 +10,7 @@ import Data.Morphisms ||| Profunctors ||| @p The action of the Profunctor on pairs of objects public export -interface Profunctor (0 p : Type -> Type -> Type) | p where +interface Profunctor (0 p : Type -> Type -> Type) where ||| Map over both arguments ||| ||| ````idris example From 9e166087eb63bc60bccae7942748c930d91b715e Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 23 May 2022 23:16:18 +0200 Subject: [PATCH 019/126] Provide type declarations for Forgotten record --- src/Data/Profunctor.idr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Profunctor.idr b/src/Data/Profunctor.idr index 3461ad3..39b02d3 100644 --- a/src/Data/Profunctor.idr +++ b/src/Data/Profunctor.idr @@ -173,7 +173,7 @@ implementation Arrow p => Profunctor (WrappedArrow p) where ||| ```` ||| public export -record Forgotten r a b where +record Forgotten (r : Type) (a : Type) (b : Type) where constructor Forget runForget : a -> r From 642a2153de3c6a21dfe4e8bbb73879702a178d83 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 23 May 2022 23:16:42 +0200 Subject: [PATCH 020/126] Rewrite WrappedArrow rmap for type disambiguation --- src/Data/Profunctor.idr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Profunctor.idr b/src/Data/Profunctor.idr index 39b02d3..4b2c732 100644 --- a/src/Data/Profunctor.idr +++ b/src/Data/Profunctor.idr @@ -160,7 +160,7 @@ implementation Arrow p => Arrow (WrappedArrow p) where export implementation Arrow p => Profunctor (WrappedArrow p) where lmap = (>>>) . arrow - rmap = (.) . arrow + rmap f = (arrow f .) -- }}} -- Forget From a551ab87a2cd9e181b07e863b69d29a388718ba8 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 24 May 2022 13:46:53 +0200 Subject: [PATCH 021/126] Import mirror from Data.Either --- src/Data/Profunctor.idr | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Data/Profunctor.idr b/src/Data/Profunctor.idr index 4b2c732..15e5eb1 100644 --- a/src/Data/Profunctor.idr +++ b/src/Data/Profunctor.idr @@ -3,6 +3,7 @@ module Data.Profunctor import Control.Monad.Identity import Control.Arrow import Control.Category +import Data.Either import Data.Morphisms %default total From 8e4f5ddecb16ed266ae06b066287176ad39872ed Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 24 May 2022 13:51:20 +0200 Subject: [PATCH 022/126] Quantify UnsafeProfunctor free type variable --- src/Data/Profunctor/Unsafe.idr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Profunctor/Unsafe.idr b/src/Data/Profunctor/Unsafe.idr index b1df720..d67d732 100644 --- a/src/Data/Profunctor/Unsafe.idr +++ b/src/Data/Profunctor/Unsafe.idr @@ -7,7 +7,7 @@ infixr 9 #. infixl 8 .# public export -interface Profunctor p => UnsafeProfunctor (p : Type -> Type -> Type) where +interface Profunctor p => UnsafeProfunctor (0 p : Type -> Type -> Type) where ||| Map the second argument of a Profunctor covariantly with a function ||| which is assumed to be a cast (#.) : (b -> c) -> p a b -> p a c From a1ec34897f0618f85e3712ea8512ff56c119c26a Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 24 May 2022 14:39:21 +0200 Subject: [PATCH 023/126] Substitute liftA2 with map and ap --- src/Data/Profunctor/Cayley.idr | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Data/Profunctor/Cayley.idr b/src/Data/Profunctor/Cayley.idr index 3c1c1c1..6b8fb63 100644 --- a/src/Data/Profunctor/Cayley.idr +++ b/src/Data/Profunctor/Cayley.idr @@ -41,22 +41,22 @@ implementation (Functor f, Choice p) => Choice (Cayleyed f p) where export implementation (Applicative f, Category p) => Category (Cayleyed f p) where id = Cayley $ pure id - (Cayley fpbc) . (Cayley fpab) = Cayley $ liftA2 (.) fpbc fpab + (Cayley fpbc) . (Cayley fpab) = Cayley $ (.) <$> fpbc <*> fpab export implementation (Applicative f, Arrow p) => Arrow (Cayleyed f p) where arrow = Cayley . pure . arrow first = Cayley . map first . runCayley second = Cayley . map second . runCayley - (Cayley ab) *** (Cayley cd) = Cayley $ liftA2 (***) ab cd - (Cayley ab) &&& (Cayley ac) = Cayley $ liftA2 (&&&) ab ac + (Cayley ab) *** (Cayley cd) = Cayley $ (***) <$> ab <*> cd + (Cayley ab) &&& (Cayley ac) = Cayley $ (&&&) <$> ab <*> ac export implementation (Applicative f, ArrowChoice p) => ArrowChoice (Cayleyed f p) where left = Cayley . map left . runCayley right = Cayley . map right . runCayley - (Cayley ab) +++ (Cayley cd) = Cayley $ liftA2 (+++) ab cd - (Cayley ac) \|/ (Cayley bc) = Cayley $ liftA2 (\|/) ac bc + (Cayley ab) +++ (Cayley cd) = Cayley $ (+++) <$> ab <*> cd + (Cayley ac) \|/ (Cayley bc) = Cayley $ (\|/) <$> ac <*> bc export implementation (Applicative f, ArrowLoop p) => ArrowLoop (Cayleyed f p) where @@ -68,4 +68,4 @@ implementation (Applicative f, ArrowZero p) => ArrowZero (Cayleyed f p) where export implementation (Applicative f, ArrowPlus p) => ArrowPlus (Cayleyed f p) where - (Cayley f) <++> (Cayley g) = Cayley $ liftA2 (<++>) f g + (Cayley f) <++> (Cayley g) = Cayley $ (<++>) <$> f <*> g From e7d97ddffd736d4d7c0c633d7020ae0981ed8b47 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 24 May 2022 14:43:01 +0200 Subject: [PATCH 024/126] Quantify Closed type variable --- src/Data/Profunctor/Closed.idr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Profunctor/Closed.idr b/src/Data/Profunctor/Closed.idr index e0a495b..f3e5e30 100644 --- a/src/Data/Profunctor/Closed.idr +++ b/src/Data/Profunctor/Closed.idr @@ -9,7 +9,7 @@ import Data.Profunctor.Unsafe ||| A Closed Profunctor that allows the closed structure to pass through public export -interface Profunctor p => Closed (p : Type -> Type -> Type) where +interface Profunctor p => Closed (0 p : Type -> Type -> Type) where ||| Pass the closed structure through the Profunctor ||| ||| ````idris example From a19a4a5d94c2153b5d4781e839a96675a754ac81 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 24 May 2022 14:49:26 +0200 Subject: [PATCH 025/126] Rename type variables in Environize to prevent shadowing of Closed.Closure.x --- src/Data/Profunctor/Closed.idr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Profunctor/Closed.idr b/src/Data/Profunctor/Closed.idr index f3e5e30..4a6b028 100644 --- a/src/Data/Profunctor/Closed.idr +++ b/src/Data/Profunctor/Closed.idr @@ -88,7 +88,7 @@ data Environment : (Type -> Type -> Type) -> Type -> Type -> Type where ||| Environize $ Kleisli $ \x => Just $ reverse x ||| ```` ||| - Environize : ((z -> y) -> b) -> p x y -> (a -> z -> x) -> Environment p a b + Environize : ((c' -> b') -> b) -> p a' b' -> (a -> c' -> a') -> Environment p a b export implementation Profunctor p => Profunctor (Environment p) where From 3f83e6abf6755bf59588fc402c8b250b5d7e5d6b Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 24 May 2022 14:54:49 +0200 Subject: [PATCH 026/126] Quantify Procompose implicit type variables --- src/Data/Profunctor/Composition.idr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Profunctor/Composition.idr b/src/Data/Profunctor/Composition.idr index fccc38a..efbd646 100644 --- a/src/Data/Profunctor/Composition.idr +++ b/src/Data/Profunctor/Composition.idr @@ -10,7 +10,7 @@ public export data Procomposed : (Type -> Type -> Type) -> (Type -> Type -> Type) -> Type -> Type -> Type where ||| Compose two Profunctors - Procompose : {x,c,d : _} -> p x c -> q d x -> Procomposed p q d c + Procompose : {0 x,c,d : _} -> p x c -> q d x -> Procomposed p q d c export procomposed : Category p => Procomposed p p a b -> p a b From fbb7d9916db3206aae61304bdef7240ff7fe71e6 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 24 May 2022 14:55:08 +0200 Subject: [PATCH 027/126] Rename type variables in Rifted to prevent shadowing of Closed.Closure.x --- src/Data/Profunctor/Composition.idr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Profunctor/Composition.idr b/src/Data/Profunctor/Composition.idr index efbd646..51fc084 100644 --- a/src/Data/Profunctor/Composition.idr +++ b/src/Data/Profunctor/Composition.idr @@ -30,7 +30,7 @@ implementation Profunctor p => Functor (Procomposed p q a) where public export record Rifted (p : Type -> Type -> Type) (q : Type -> Type -> Type) a b where constructor Rift - runRift : p b x -> q a x + runRift : p b y -> q a y export implementation (Profunctor p, Profunctor q) => Profunctor (Rifted p q) where From 3bf2f8bdf99e901eb85b27a638ec993ac995cd2e Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 24 May 2022 14:57:10 +0200 Subject: [PATCH 028/126] Quantify Comonad's type variable --- src/Data/Profunctor/Comonad.idr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Profunctor/Comonad.idr b/src/Data/Profunctor/Comonad.idr index 06fbdf1..ee5e82c 100644 --- a/src/Data/Profunctor/Comonad.idr +++ b/src/Data/Profunctor/Comonad.idr @@ -5,7 +5,7 @@ import Control.Category import Data.Profunctor public export -interface Functor w => Comonad (w : Type -> Type) where +interface Functor w => Comonad (0 w : Type -> Type) where extract : w a -> a duplicate : w a -> w (w a) From ad09bd8446259bc2d1a9b61c3919a754d1bb9eb3 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 24 May 2022 16:50:09 +0200 Subject: [PATCH 029/126] Rename & operator to .& --- src/Data/Profunctor/Iso.idr | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Data/Profunctor/Iso.idr b/src/Data/Profunctor/Iso.idr index d047aef..23c2b49 100644 --- a/src/Data/Profunctor/Iso.idr +++ b/src/Data/Profunctor/Iso.idr @@ -2,11 +2,11 @@ module Data.Profunctor.Iso import Data.Profunctor -infixl 1 & +infixl 1 .& export -(&) : a -> (a -> b) -> b -a & f = f a +(.&) : a -> (a -> b) -> b +a .& f = f a ||| A type-level function to make it easier to talk about "simple" `Lens`, ||| `Prism`, and `Iso`s From 9abde469f78a5e516966591fdd54fb1d5b27810e Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 24 May 2022 16:50:26 +0200 Subject: [PATCH 030/126] Import mirror from Data.Either --- src/Data/Profunctor/Iso.idr | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Data/Profunctor/Iso.idr b/src/Data/Profunctor/Iso.idr index 23c2b49..89356ec 100644 --- a/src/Data/Profunctor/Iso.idr +++ b/src/Data/Profunctor/Iso.idr @@ -1,5 +1,6 @@ module Data.Profunctor.Iso +import Data.Either import Data.Profunctor infixl 1 .& From 0fce330289af2388852cb227bcc48b9d7c2c953f Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 24 May 2022 16:50:57 +0200 Subject: [PATCH 031/126] Remove explicit implicit type from function implementation --- src/Data/Profunctor/Iso.idr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Profunctor/Iso.idr b/src/Data/Profunctor/Iso.idr index 89356ec..622a850 100644 --- a/src/Data/Profunctor/Iso.idr +++ b/src/Data/Profunctor/Iso.idr @@ -23,7 +23,7 @@ Simple t s a = t s s a a public export preIso : {p : Type -> Type -> Type} -> Type -> Type -> Type -> Type -> Type -preIso {p} s t a b = p a b -> p s t +preIso s t a b = p a b -> p s t ||| An isomorphism family. public export From 3facaa4fe9aacd77a1a6835bd592762901685ce9 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 24 May 2022 16:51:35 +0200 Subject: [PATCH 032/126] Fix Profunctor type restriction in Iso and Iso' --- src/Data/Profunctor/Iso.idr | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Data/Profunctor/Iso.idr b/src/Data/Profunctor/Iso.idr index 622a850..eeec2b3 100644 --- a/src/Data/Profunctor/Iso.idr +++ b/src/Data/Profunctor/Iso.idr @@ -27,13 +27,13 @@ preIso s t a b = p a b -> p s t ||| An isomorphism family. public export -Iso : Profunctor p => Type -> Type -> Type -> Type -> Type -Iso {p} = preIso {p} +Iso : {p : Type -> Type -> Type} -> Type -> Type -> Type -> Type -> Type +Iso s t a b = Profunctor p => preIso {p} s t a b ||| An isomorphism family that does not change types public export -Iso' : Profunctor p => Type -> Type -> Type -Iso' {p} = Simple $ Iso {p} +Iso' : {p : Type -> Type -> Type} -> Type -> Type -> Type +Iso' s a = Simple (Iso {p}) s a ||| Turns a coavariant and contravariant function into an `Iso` export From f9dfeaf15aa6ce851bb8bbe13d7c570a20898e5c Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 24 May 2022 16:52:18 +0200 Subject: [PATCH 033/126] Explicitly apply Force and Delay --- src/Data/Profunctor/Iso.idr | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/Data/Profunctor/Iso.idr b/src/Data/Profunctor/Iso.idr index eeec2b3..57e9a0b 100644 --- a/src/Data/Profunctor/Iso.idr +++ b/src/Data/Profunctor/Iso.idr @@ -48,9 +48,8 @@ lensIso gt = iso (\s => (gt s, s)) . uncurry . flip ||| Builds an `Iso` useful for constructing a `Prism` export -prismIso : Profunctor p => (b -> t) -> (s -> Either t a) -> - Iso {p} s t (Either t a) (Either t b) -prismIso = flip iso . either id . Delay +prismIso : (b -> t) -> (s -> Either t a) -> Iso {p} s t (Either t a) (Either t b) +prismIso f = flip iso $ either id $ Delay f ||| Convert an element of the first half of an iso to the second export @@ -97,13 +96,23 @@ unpacked = iso pack unpack ||| An `Iso` between a lazy variable and its strict form export -motivated : Profunctor p => Iso {p} a b (Lazy a) (Lazy b) -motivated = iso Delay Force +motivated : Iso {p} a b (Lazy a) (Lazy b) +motivated = let + snooze : a -> Lazy a + snooze x = Delay x + ring : Lazy b -> b + ring x = Force x + in iso snooze ring ||| An `Iso` between a strict variable and its lazy form export -unmotivated : Profunctor p => Iso {p} (Lazy a) (Lazy b) a b -unmotivated = iso Force Delay +unmotivated : Iso {p} (Lazy a) (Lazy b) a b +unmotivated = let + snooze : b -> Lazy b + snooze x = Delay x + ring : Lazy a -> a + ring x = Force x + in iso ring snooze ||| An `Iso` between an enumerable value and it's `Nat` representation export From f5a58ecc9bce2769ed2821dc3c5b7c081a2a152e Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 24 May 2022 16:53:42 +0200 Subject: [PATCH 034/126] Comment out enum and denum relying on Enum in base --- src/Data/Profunctor/Iso.idr | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/Data/Profunctor/Iso.idr b/src/Data/Profunctor/Iso.idr index 57e9a0b..6a67e62 100644 --- a/src/Data/Profunctor/Iso.idr +++ b/src/Data/Profunctor/Iso.idr @@ -114,15 +114,17 @@ unmotivated = let ring x = Force x in iso ring snooze -||| An `Iso` between an enumerable value and it's `Nat` representation -export -enum : (Profunctor p, Enum a) => Iso' {p} Nat a -enum = iso fromNat toNat - -||| An `Iso` between a `Nat` and its enumerable representation -export -denum : (Profunctor p, Enum a) => Iso' {p} a Nat -denum = iso toNat fromNat +-- TODO: Enum is currently commented out of base +-- +-- ||| An `Iso` between an enumerable value and it's `Nat` representation +-- export +-- enum : (Profunctor p, Enum a) => Iso' {p} Nat a +-- enum = iso fromNat toNat +-- +-- ||| An `Iso` between a `Nat` and its enumerable representation +-- export +-- denum : (Profunctor p, Enum a) => Iso' {p} a Nat +-- denum = iso toNat fromNat export mirrored : Profunctor p => Iso {p} (Either a b) (Either c d) From d73944869f52f59c21c657c140b953cdeb234e75 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 24 May 2022 16:54:19 +0200 Subject: [PATCH 035/126] Remove top level Profunctor resrictions --- src/Data/Profunctor/Iso.idr | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/Data/Profunctor/Iso.idr b/src/Data/Profunctor/Iso.idr index 6a67e62..7be65de 100644 --- a/src/Data/Profunctor/Iso.idr +++ b/src/Data/Profunctor/Iso.idr @@ -37,13 +37,12 @@ Iso' s a = Simple (Iso {p}) s a ||| Turns a coavariant and contravariant function into an `Iso` export -iso : Profunctor p => (s -> a) -> (b -> t) -> Iso {p} s t a b -iso = dimap +iso : (s -> a) -> (b -> t) -> Iso {p} s t a b +iso f g = dimap f g ||| Builds an `Iso` useful for constructing a `Lens` export -lensIso : Profunctor p => - (s -> a) -> (s -> b -> t) -> Iso {p} s t (a, s) (b, s) +lensIso : (s -> a) -> (s -> b -> t) -> Iso {p} s t (a, s) (b, s) lensIso gt = iso (\s => (gt s, s)) . uncurry . flip ||| Builds an `Iso` useful for constructing a `Prism` @@ -63,35 +62,35 @@ backwards i = runTagged . i . Tag ||| An `Iso` between a function and it's arguments-flipped version export -flipped : Profunctor p => Iso {p} (a -> b -> c) (d -> e -> f) - (b -> a -> c) (e -> d -> f) +flipped : Iso {p} (a -> b -> c) (d -> e -> f) + (b -> a -> c) (e -> d -> f) flipped = iso flip flip ||| An `Iso` between a function and it's curried version export -curried : Profunctor p => Iso {p} ((a, b) -> c) ((d, e) -> f) - (a -> b -> c) (d -> e -> f) +curried : Iso {p} ((a, b) -> c) ((d, e) -> f) + (a -> b -> c) (d -> e -> f) curried = iso curry uncurry ||| An `Iso` between a function and it's uncurried version export -uncurried : Profunctor p => Iso {p} (a -> b -> c) (d -> e -> f) - ((a, b) -> c) ((d, e) -> f) +uncurried : Iso {p} (a -> b -> c) (d -> e -> f) + ((a, b) -> c) ((d, e) -> f) uncurried = iso uncurry curry ||| An `Iso` between a list and its reverse export -reversed : Profunctor p => Iso {p} (List a) (List b) (List a) (List b) +reversed : Iso {p} (List a) (List b) (List a) (List b) reversed = iso reverse reverse ||| An `Iso` between a string and a list of its characters export -packed : Profunctor p => Iso' {p} String (List Char) +packed : Iso' {p} String (List Char) packed = iso unpack pack ||| An `Iso` between a list of characters and its string export -unpacked : Profunctor p => Iso' {p} (List Char) String +unpacked : Iso' {p} (List Char) String unpacked = iso pack unpack ||| An `Iso` between a lazy variable and its strict form @@ -127,6 +126,6 @@ unmotivated = let -- denum = iso toNat fromNat export -mirrored : Profunctor p => Iso {p} (Either a b) (Either c d) - (Either b a) (Either d c) +mirrored : Iso {p} (Either a b) (Either c d) + (Either b a) (Either d c) mirrored = iso mirror mirror From b3b3f08e6c4c023b034314ae92ad1e5da18958b2 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Wed, 25 May 2022 08:26:15 +0200 Subject: [PATCH 036/126] Remove redundant implicit typing --- src/Data/Profunctor/Iso.idr | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/Data/Profunctor/Iso.idr b/src/Data/Profunctor/Iso.idr index 7be65de..a133221 100644 --- a/src/Data/Profunctor/Iso.idr +++ b/src/Data/Profunctor/Iso.idr @@ -37,17 +37,17 @@ Iso' s a = Simple (Iso {p}) s a ||| Turns a coavariant and contravariant function into an `Iso` export -iso : (s -> a) -> (b -> t) -> Iso {p} s t a b +iso : (s -> a) -> (b -> t) -> Iso s t a b iso f g = dimap f g ||| Builds an `Iso` useful for constructing a `Lens` export -lensIso : (s -> a) -> (s -> b -> t) -> Iso {p} s t (a, s) (b, s) +lensIso : (s -> a) -> (s -> b -> t) -> Iso s t (a, s) (b, s) lensIso gt = iso (\s => (gt s, s)) . uncurry . flip ||| Builds an `Iso` useful for constructing a `Prism` export -prismIso : (b -> t) -> (s -> Either t a) -> Iso {p} s t (Either t a) (Either t b) +prismIso : (b -> t) -> (s -> Either t a) -> Iso s t (Either t a) (Either t b) prismIso f = flip iso $ either id $ Delay f ||| Convert an element of the first half of an iso to the second @@ -62,40 +62,40 @@ backwards i = runTagged . i . Tag ||| An `Iso` between a function and it's arguments-flipped version export -flipped : Iso {p} (a -> b -> c) (d -> e -> f) - (b -> a -> c) (e -> d -> f) +flipped : Iso (a -> b -> c) (d -> e -> f) + (b -> a -> c) (e -> d -> f) flipped = iso flip flip ||| An `Iso` between a function and it's curried version export -curried : Iso {p} ((a, b) -> c) ((d, e) -> f) - (a -> b -> c) (d -> e -> f) +curried : Iso ((a, b) -> c) ((d, e) -> f) + (a -> b -> c) (d -> e -> f) curried = iso curry uncurry ||| An `Iso` between a function and it's uncurried version export -uncurried : Iso {p} (a -> b -> c) (d -> e -> f) - ((a, b) -> c) ((d, e) -> f) +uncurried : Iso (a -> b -> c) (d -> e -> f) + ((a, b) -> c) ((d, e) -> f) uncurried = iso uncurry curry ||| An `Iso` between a list and its reverse export -reversed : Iso {p} (List a) (List b) (List a) (List b) +reversed : Iso (List a) (List b) (List a) (List b) reversed = iso reverse reverse ||| An `Iso` between a string and a list of its characters export -packed : Iso' {p} String (List Char) +packed : Iso' String (List Char) packed = iso unpack pack ||| An `Iso` between a list of characters and its string export -unpacked : Iso' {p} (List Char) String +unpacked : Iso' (List Char) String unpacked = iso pack unpack ||| An `Iso` between a lazy variable and its strict form export -motivated : Iso {p} a b (Lazy a) (Lazy b) +motivated : Iso a b (Lazy a) (Lazy b) motivated = let snooze : a -> Lazy a snooze x = Delay x @@ -105,7 +105,7 @@ motivated = let ||| An `Iso` between a strict variable and its lazy form export -unmotivated : Iso {p} (Lazy a) (Lazy b) a b +unmotivated : Iso (Lazy a) (Lazy b) a b unmotivated = let snooze : b -> Lazy b snooze x = Delay x @@ -126,6 +126,6 @@ unmotivated = let -- denum = iso toNat fromNat export -mirrored : Iso {p} (Either a b) (Either c d) - (Either b a) (Either d c) +mirrored : Iso (Either a b) (Either c d) + (Either b a) (Either d c) mirrored = iso mirror mirror From 735789d0e2609bdbe867372c0e044083a95fd8ba Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Wed, 25 May 2022 10:59:27 +0200 Subject: [PATCH 037/126] Quantify Lensing's type variable --- src/Data/Profunctor/Lens.idr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Profunctor/Lens.idr b/src/Data/Profunctor/Lens.idr index 06fb988..dd96dec 100644 --- a/src/Data/Profunctor/Lens.idr +++ b/src/Data/Profunctor/Lens.idr @@ -11,7 +11,7 @@ import Data.Vect ||| A `Strong` `Profunctor` that can be used in a `Lens` public export -interface Strong p => Lensing (p : Type -> Type -> Type) where +interface Strong p => Lensing (0 p : Type -> Type -> Type) where strength : p a b -> p (b -> t, a) t strength = (rmap $ uncurry id) . second' From 931747d466c33cc397d35b1bb70da7da7d95eba1 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Wed, 25 May 2022 11:01:19 +0200 Subject: [PATCH 038/126] Fix Lensing type restriction in Iso and Iso' --- src/Data/Profunctor/Lens.idr | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Data/Profunctor/Lens.idr b/src/Data/Profunctor/Lens.idr index dd96dec..d7ca8ec 100644 --- a/src/Data/Profunctor/Lens.idr +++ b/src/Data/Profunctor/Lens.idr @@ -29,13 +29,13 @@ implementation Lensing Morphism where ||| A Lens family, strictly speaking, or a polymorphic lens. public export -Lens : Lensing p => Type -> Type -> Type -> Type -> Type -Lens {p} = preIso {p} +Lens : {p : Type -> Type -> Type} -> Type -> Type -> Type -> Type -> Type +Lens s t a b = Lensing p => preIso {p} s t a b ||| A Lens family that does not change types public export -Lens' : Lensing p => Type -> Type -> Type -Lens' {p} = Simple $ Lens {p} +Lens' : {p : Type -> Type -> Type} -> Type -> Type -> Type +Lens' s a = Simple (Lens {p}) s a ||| Build a `Lens` out of a function. Note this takes one argument, not two export From 272a1e71a106efd4cf418bb61ba41694294a6812 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Wed, 25 May 2022 11:09:37 +0200 Subject: [PATCH 039/126] Remove top level Lensing resrictions --- src/Data/Profunctor/Lens.idr | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Data/Profunctor/Lens.idr b/src/Data/Profunctor/Lens.idr index d7ca8ec..b074110 100644 --- a/src/Data/Profunctor/Lens.idr +++ b/src/Data/Profunctor/Lens.idr @@ -39,12 +39,12 @@ Lens' s a = Simple (Lens {p}) s a ||| Build a `Lens` out of a function. Note this takes one argument, not two export -lens' : Lensing p => (s -> (b -> t, a)) -> Lens {p} s t a b +lens' : (s -> (b -> t, a)) -> Lens {p} s t a b lens' f = lmap f . strength ||| Build a `Lens` out of getter and setter export -lens : Lensing p => (s -> a) -> (s -> b -> t) -> Lens {p} s t a b +lens : (s -> a) -> (s -> b -> t) -> Lens {p} s t a b lens gt st = lens' $ \s => (\b => st s b, gt s) export @@ -53,7 +53,7 @@ foldMapOf l f = runForget $ l $ Forget f export foldrOf : Lens {p=Forgotten (Endomorphism r)} s t a b -> (a -> r -> r) -> r -> s -> r -foldrOf p f = flip $ applyEndo . foldMapOf p (Endo . f) +foldrOf p f = flip $ applyEndo . foldMapOf p (Endo . f) public export Getter : Type -> Type -> Type -> Type -> Type @@ -98,7 +98,7 @@ export export sets : ((a -> b) -> s -> t) -> Lens {p=Morphism} s t a b -sets l (Mor f) = Mor $ l f +sets l (Mor f) = Mor $ l f ||| Set something to a specific value with a Lens export @@ -159,31 +159,31 @@ export ||| A Lens for the first element of a tuple export -_1 : Lensing p => Lens {p} (a, b) (x, b) a x +_1 : Lens {p} (a, b) (x, b) a x _1 = lens' $ \(a,b) => (flip MkPair b, a) ||| A Lens for the second element of a tuple export -_2 : Lensing p => Lens {p} (b, a) (b, x) a x +_2 : Lens {p} (b, a) (b, x) a x _2 = lens' $ \(b,a) => (MkPair b, a) ||| A Lens for the first element of a non-empty vector export -_vCons : Lensing p => Lens {p} (Vect (S n) a) (Vect (S n) b) - (a, Vect n a) (b, Vect n b) +_vCons : Lens {p} (Vect (S n) a) (Vect (S n) b) + (a, Vect n a) (b, Vect n b) _vCons = lens' $ \(x::xs) => (uncurry (::), (x,xs)) ||| A Lens for the nth element of a big-enough vector export -_vNth : Lensing p => {m : Nat} -> (n : Fin (S m)) -> +_vNth : {m : Nat} -> (n : Fin (S m)) -> Lens {p} (Vect (S m) a) (Vect (S m) b) (a, Vect m a) (b, Vect m b) _vNth n = lens' $ \v => (uncurry $ insertAt n, (index n v, deleteAt n v)) ||| A Lens for the nth element of a big-enough heterogenous vector export -_hVNth : Lensing p => (i : Fin (S l)) -> Lens {p} (HVect us) (HVect vs) - (index i us, HVect (deleteAt i us)) - (index i vs, HVect (deleteAt i vs)) +_hVNth : (i : Fin (S l)) -> Lens {p} (HVect us) (HVect vs) + (index i us, HVect (deleteAt i us)) + (index i vs, HVect (deleteAt i vs)) _hVNth n = lens' $ \v => (believe_me . uncurry (insertAt' n), (index n v, deleteAt n v)) where insertAt' : (i : Fin (S l)) -> a -> HVect us -> HVect (insertAt i a us) @@ -193,5 +193,5 @@ _hVNth n = lens' $ \v => ||| Everything has a `()` in it export -devoid : Lensing p => Lens' {p} a () +devoid : Lens' {p} a () devoid = lens' $ flip MkPair () . const From 964c95c2523866f67b07643549808e2493248f73 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Wed, 25 May 2022 11:10:04 +0200 Subject: [PATCH 040/126] Rename HVect type variable to avoid clash --- src/Data/Profunctor/Lens.idr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Profunctor/Lens.idr b/src/Data/Profunctor/Lens.idr index b074110..03c7ce5 100644 --- a/src/Data/Profunctor/Lens.idr +++ b/src/Data/Profunctor/Lens.idr @@ -186,7 +186,7 @@ _hVNth : (i : Fin (S l)) -> Lens {p} (HVect us) (HVect vs) (index i vs, HVect (deleteAt i vs)) _hVNth n = lens' $ \v => (believe_me . uncurry (insertAt' n), (index n v, deleteAt n v)) where - insertAt' : (i : Fin (S l)) -> a -> HVect us -> HVect (insertAt i a us) + insertAt' : (i : Fin (S k)) -> a -> HVect ws -> HVect (insertAt i a ws) insertAt' FZ y xs = y :: xs insertAt' (FS k) y (x::xs) = x :: insertAt' k y xs insertAt' (FS k) y [] = absurd k From bf1760c0b89c6164baf05541a71891b81e414869 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Wed, 25 May 2022 11:15:49 +0200 Subject: [PATCH 041/126] Fix typing of view --- src/Data/Profunctor/Lens.idr | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Data/Profunctor/Lens.idr b/src/Data/Profunctor/Lens.idr index 03c7ce5..f477d3a 100644 --- a/src/Data/Profunctor/Lens.idr +++ b/src/Data/Profunctor/Lens.idr @@ -62,7 +62,10 @@ Getter s t a = Lens {p=Forgotten a} s t a ||| Build a function to look at stuff from a Lens export view : Getter s t a b -> s -> a -view = runForget . (\f => f $ Forget id) +view = runForget . go + where go : (Lensing (Forgotten a) => + Forgotten a a b -> Forgotten a s t) -> Forgotten a s t + go f = f $ Forget id ||| Create a getter from arbitrary function `s -> a`. export From b8ec8a94630604b3cff9b056547d9f0b5ed52ba8 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Wed, 25 May 2022 11:16:08 +0200 Subject: [PATCH 042/126] Fix type check of over --- src/Data/Profunctor/Lens.idr | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Data/Profunctor/Lens.idr b/src/Data/Profunctor/Lens.idr index f477d3a..7232a75 100644 --- a/src/Data/Profunctor/Lens.idr +++ b/src/Data/Profunctor/Lens.idr @@ -91,7 +91,9 @@ s ^? l = foldMapOf l Just s ||| Build a function to `map` from a Lens export over : Lens {p=Morphism} s t a b -> (a -> b) -> s -> t -over = (applyMor .) . (. Mor) +over = (applyMor .) . go + where go : (Lensing Morphism => Morphism a b -> Morphism s t) -> (a -> b) -> Morphism s t + go = (. Mor) infixr 4 &~ ||| Infix synonym for `over` From 60b69724934e51d5db2cf50dd7b5d593cbde7bae Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Wed, 25 May 2022 11:42:16 +0200 Subject: [PATCH 043/126] Prepent Prism accessor functions with leading p --- src/Data/Profunctor/Prism.idr | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Data/Profunctor/Prism.idr b/src/Data/Profunctor/Prism.idr index 099aee8..679238c 100644 --- a/src/Data/Profunctor/Prism.idr +++ b/src/Data/Profunctor/Prism.idr @@ -72,35 +72,35 @@ review = (runTagged .) . (. Tag) ||| A `Prism` for the left half of an `Either` export -_l : Prisming p => Prism {p} (Either a c) (Either b c) a b -_l = prism Left $ either Right (Left . Right) +p_l : Prisming p => Prism {p} (Either a c) (Either b c) a b +p_l = prism Left $ either Right (Left . Right) ||| A `Prism` for the right half of an `Either` export -_r : Prisming p => Prism {p} (Either c a) (Either c b) a b -_r = prism Right $ either (Left . Left) Right +p_r : Prisming p => Prism {p} (Either c a) (Either c b) a b +p_r = prism Right $ either (Left . Left) Right ||| A `Prism` for the just case of a `Maybe` export -_j : Prisming p => Prism {p} (Maybe a) (Maybe b) a b -_j = prism Just $ maybe (Left Nothing) Right +p_j : Prisming p => Prism {p} (Maybe a) (Maybe b) a b +p_j = prism Just $ maybe (Left Nothing) Right ||| A `Prism` for the nothing case of a `Maybe` export -_n : Prisming p => Prism' {p} (Maybe a) () -_n = prism' (const Nothing) . maybe (Just ()) $ const Nothing +p_n : Prisming p => Prism' {p} (Maybe a) () +p_n = prism' (const Nothing) . maybe (Just ()) $ const Nothing ||| A `Prism` for the left side of a `List` export -_lCons : Prisming p => Prism {p} (List a) (List b) (a, List a) (b, List b) -_lCons = prism (uncurry (::)) $ \aas => case aas of +p_lCons : Prisming p => Prism {p} (List a) (List b) (a, List a) (b, List b) +p_lCons = prism (uncurry (::)) $ \aas => case aas of (a::as) => Right (a, as) [] => Left [] ||| A `Prism` for the left side of a `String` export -_strCons : Prisming p => Prism' {p} String (Char, String) -_strCons = prism (uncurry strCons) $ \aas => case unpack aas of +p_strCons : Prisming p => Prism' {p} String (Char, String) +p_strCons = prism (uncurry strCons) $ \aas => case unpack aas of (a::as) => Right (a, pack as) [] => Left "" From 5336e0ae2ae8deab28b70f7fef6577a34f975af3 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Wed, 25 May 2022 11:54:05 +0200 Subject: [PATCH 044/126] Add isNothing to imports --- src/Data/Profunctor/Prism.idr | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Data/Profunctor/Prism.idr b/src/Data/Profunctor/Prism.idr index 679238c..46c8cb6 100644 --- a/src/Data/Profunctor/Prism.idr +++ b/src/Data/Profunctor/Prism.idr @@ -1,6 +1,7 @@ module Data.Profunctor.Prism import Data.Morphisms +import Data.Maybe import Data.Profunctor import Data.Profunctor.Choice import Data.Profunctor.Iso From 3fbf65d16bb867926ed235f6e1c118aaf058d22c Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Wed, 25 May 2022 11:55:10 +0200 Subject: [PATCH 045/126] Add lambda for Delay call --- src/Data/Profunctor/Prism.idr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Profunctor/Prism.idr b/src/Data/Profunctor/Prism.idr index 46c8cb6..f6d08f0 100644 --- a/src/Data/Profunctor/Prism.idr +++ b/src/Data/Profunctor/Prism.idr @@ -14,7 +14,7 @@ interface Choice p => Prisming (p : Type -> Type -> Type) where export implementation Prisming Morphism where - costrength = Mor . either id . Delay . applyMor + costrength = Mor . either id . (\x => Delay x) . applyMor export implementation Monoid r => Prisming (Forgotten r) where From cfde27779ebb4d2dc0d293605485cc00daba8dc2 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Wed, 25 May 2022 13:20:24 +0200 Subject: [PATCH 046/126] Wrap laziness keywords in lambdas --- src/Data/Profunctor/Fold.idr | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Data/Profunctor/Fold.idr b/src/Data/Profunctor/Fold.idr index ca58133..624e560 100644 --- a/src/Data/Profunctor/Fold.idr +++ b/src/Data/Profunctor/Fold.idr @@ -167,27 +167,27 @@ sort = MkL id (flip $ merge . pure) [] where ||| Turns a binary function into a lazy `L` export L1 : (a -> a -> a) -> L a (Lazy (Maybe a)) -L1 s = MkL Delay (\m => Just . case m of Just x => s x; _ => id) Nothing +L1 s = MkL (\x => Delay x) (\m => Just . case m of Just x => s x; _ => id) Nothing ||| Returns the first element of its input, if it exists export first : L a (Maybe a) -first = map Force $ L1 const +first = map (x => Force x) $ L1 const ||| Returns the last element of its input, if it exists export last : L a (Maybe a) -last = map Force . L1 $ flip const +last = map (x => Force x) . L1 $ flip const ||| Returns the maximum element of its input, if it exists export maximum : Ord a => L a (Maybe a) -maximum = map Force $ L1 max +maximum = map (x => Force x) $ L1 max ||| Returns the minimum element of its input, if it exists export minimum : Ord a => L a (Maybe a) -minimum = map Force $ L1 min +minimum = map (x => Force x) $ L1 min ||| Sums the elements of its input export From 2de86db85aa36a46b2e74ba71332546e4ace8ed7 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Wed, 25 May 2022 13:23:45 +0200 Subject: [PATCH 047/126] Substitute liftA2 with map and ap --- src/Data/Profunctor/Fold.idr | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/Data/Profunctor/Fold.idr b/src/Data/Profunctor/Fold.idr index 624e560..1d1ab18 100644 --- a/src/Data/Profunctor/Fold.idr +++ b/src/Data/Profunctor/Fold.idr @@ -73,7 +73,7 @@ implementation Monad (L a) where export implementation Semigroup m => Semigroup (L a m) where - (<+>) = liftA2 (<+>) + x <+> y = (<+>) <$> x <*> y export implementation Monoid m => Monoid (L a m) where @@ -88,7 +88,7 @@ implementation AbelianGroup m => AbelianGroup (L a m) where export implementation Ring m => Ring (L a m) where - (<.>) = liftA2 (<.>) + x <.> y = (<.>) <$> x <*> y export implementation RingWithUnity m => RingWithUnity (L a m) where @@ -98,20 +98,19 @@ implementation RingWithUnity m => RingWithUnity (L a m) where export implementation Num n => Num (L a n) where - (+) = liftA2 (+) - (*) = liftA2 (*) + x + y = (+) <$> x <*> y + x * y = (*) <$> x <*> y fromInteger = pure . fromInteger export implementation Neg n => Neg (L a n) where - (-) = liftA2 (-) + x - y = (-) <$> x <*> y negate = map negate export implementation Abs n => Abs (L a n) where abs = map abs - ||| An `L` to calculate the size of a `Foldable` container export length : Num a => L _ a @@ -271,7 +270,7 @@ implementation Monad (R a) where export implementation Semigroup m => Semigroup (R a m) where - (<+>) = liftA2 (<+>) + x <+> y = (<+>) <$> x <*> y export implementation Monoid m => Monoid (R a m) where @@ -279,13 +278,13 @@ implementation Monoid m => Monoid (R a m) where export implementation Num n => Num (R a n) where - (+) = liftA2 (+) - (*) = liftA2 (*) + x + y = (+) <$> x <*> y + x * y = (*) <$> x <*> y fromInteger = pure . fromInteger export implementation Neg n => Neg (R a n) where - (-) = liftA2 (-) + x - y = (-) <$> x <*> y negate = map negate export @@ -301,7 +300,7 @@ implementation AbelianGroup m => AbelianGroup (R a m) where export implementation Ring m => Ring (R a m) where - (<.>) = liftA2 (<.>) + x <.> y = (<.>) <$> x <*> y export implementation RingWithUnity m => RingWithUnity (R a m) where From 8e236aef1af31ed686dc3b68015ea54046d46616 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 30 May 2022 09:57:39 +0200 Subject: [PATCH 048/126] ipkg: Fix sourcedir value has type string --- profunctors.ipkg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/profunctors.ipkg b/profunctors.ipkg index 8963274..9e45f68 100644 --- a/profunctors.ipkg +++ b/profunctors.ipkg @@ -1,6 +1,6 @@ package profunctors -sourcedir = src +sourcedir = "src" modules = Data.Profunctor , Data.Profunctor.Cayley From e530e1e76add858f7bc5e96d4a0333392ddc05e3 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 30 May 2022 09:58:12 +0200 Subject: [PATCH 049/126] Unify snooze and ring functions --- src/Data/Profunctor/Iso.idr | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/Data/Profunctor/Iso.idr b/src/Data/Profunctor/Iso.idr index a133221..e46f07f 100644 --- a/src/Data/Profunctor/Iso.idr +++ b/src/Data/Profunctor/Iso.idr @@ -93,25 +93,20 @@ export unpacked : Iso' (List Char) String unpacked = iso pack unpack +snooze : a -> Lazy a +snooze x = Delay x +ring : Lazy b -> b +ring x = Force x + ||| An `Iso` between a lazy variable and its strict form export motivated : Iso a b (Lazy a) (Lazy b) -motivated = let - snooze : a -> Lazy a - snooze x = Delay x - ring : Lazy b -> b - ring x = Force x - in iso snooze ring +motivated = iso snooze ring ||| An `Iso` between a strict variable and its lazy form export unmotivated : Iso (Lazy a) (Lazy b) a b -unmotivated = let - snooze : b -> Lazy b - snooze x = Delay x - ring : Lazy a -> a - ring x = Force x - in iso ring snooze +unmotivated = iso ring snooze -- TODO: Enum is currently commented out of base -- From b7ab0478e3d1a1ae862822769c3d02158961dadc Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 30 May 2022 10:06:56 +0200 Subject: [PATCH 050/126] Fix Prisming type restriction in Prism and Prism' --- src/Data/Profunctor/Prism.idr | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Data/Profunctor/Prism.idr b/src/Data/Profunctor/Prism.idr index f6d08f0..69cad7a 100644 --- a/src/Data/Profunctor/Prism.idr +++ b/src/Data/Profunctor/Prism.idr @@ -30,21 +30,21 @@ implementation Prisming Tagged where ||| A `Lens` for sum types instead of product types public export -Prism : Prisming p => Type -> Type -> Type -> Type -> Type -Prism {p} = preIso {p} +Prism : {p : Type -> Type -> Type} -> Type -> Type -> Type -> Type -> Type +Prism s t a b = Prisming p => preIso {p} s t a b ||| A Prism that does not change types public export -Prism' : Prisming p => Type -> Type -> Type -Prism' {p} = Simple $ Prism {p} +Prism' : {p : Type -> Type -> Type} -> Type -> Type -> Type +Prism' s a = Simple (Prism {p}) s a ||| Build a `Prism` from two functions export -prism : Prisming p => (b -> t) -> (s -> Either t a) -> Prism {p} s t a b +prism : (b -> t) -> (s -> Either t a) -> Prism {p} s t a b prism f g = lmap g . costrength . rmap f export -prism' : Prisming p => (b -> s) -> (s -> Maybe a) -> Prism {p} s s a b +prism' : (b -> s) -> (s -> Maybe a) -> Prism {p} s s a b prism' f g = prism f $ \s => maybe (Left s) Right $ g s public export From ddac1e95d0e797d26b52a90eb81a16f564339c81 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 30 May 2022 10:07:44 +0200 Subject: [PATCH 051/126] Explicitly type helper function of review --- src/Data/Profunctor/Prism.idr | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Data/Profunctor/Prism.idr b/src/Data/Profunctor/Prism.idr index 69cad7a..cb3f692 100644 --- a/src/Data/Profunctor/Prism.idr +++ b/src/Data/Profunctor/Prism.idr @@ -69,7 +69,9 @@ preview l = runFirst . runForget (l . Forget $ MkFirst . Just) ||| Build a function from a `Prism` to `map` export review : Prism {p=Tagged} s t a b -> b -> t -review = (runTagged .) . (. Tag) +review = (runTagged .) . go + where go : (Prisming Tagged => Tagged a b -> Tagged s t) -> b -> Tagged s t + go = (. Tag) ||| A `Prism` for the left half of an `Either` export From e164161f0f89132c967eece0f1d0c544a0494ff0 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 30 May 2022 10:08:23 +0200 Subject: [PATCH 052/126] Fix Prisming type restriciton in prism functions --- src/Data/Profunctor/Prism.idr | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Data/Profunctor/Prism.idr b/src/Data/Profunctor/Prism.idr index cb3f692..2dee58c 100644 --- a/src/Data/Profunctor/Prism.idr +++ b/src/Data/Profunctor/Prism.idr @@ -75,46 +75,46 @@ review = (runTagged .) . go ||| A `Prism` for the left half of an `Either` export -p_l : Prisming p => Prism {p} (Either a c) (Either b c) a b +p_l : Prism {p} (Either a c) (Either b c) a b p_l = prism Left $ either Right (Left . Right) ||| A `Prism` for the right half of an `Either` export -p_r : Prisming p => Prism {p} (Either c a) (Either c b) a b +p_r : Prism {p} (Either c a) (Either c b) a b p_r = prism Right $ either (Left . Left) Right ||| A `Prism` for the just case of a `Maybe` export -p_j : Prisming p => Prism {p} (Maybe a) (Maybe b) a b +p_j : Prism {p} (Maybe a) (Maybe b) a b p_j = prism Just $ maybe (Left Nothing) Right ||| A `Prism` for the nothing case of a `Maybe` export -p_n : Prisming p => Prism' {p} (Maybe a) () +p_n : Prism' {p} (Maybe a) () p_n = prism' (const Nothing) . maybe (Just ()) $ const Nothing ||| A `Prism` for the left side of a `List` export -p_lCons : Prisming p => Prism {p} (List a) (List b) (a, List a) (b, List b) +p_lCons : Prism {p} (List a) (List b) (a, List a) (b, List b) p_lCons = prism (uncurry (::)) $ \aas => case aas of (a::as) => Right (a, as) [] => Left [] ||| A `Prism` for the left side of a `String` export -p_strCons : Prisming p => Prism' {p} String (Char, String) +p_strCons : Prism' {p} String (Char, String) p_strCons = prism (uncurry strCons) $ \aas => case unpack aas of (a::as) => Right (a, pack as) [] => Left "" ||| A prism for equality export -only : (Eq a, Prisming p) => a -> Prism' {p} a () +only : Eq a => a -> Prism' {p} a () only a = prism (const a) $ \x => if x == a then Left x else Right () ||| A prism for near-equality, as determined by a given predicate export -nearly : Prisming p => a -> (a -> Bool) -> Prism' {p} a () +nearly : a -> (a -> Bool) -> Prism' {p} a () nearly a p = prism (const a) $ if p a then Left else const $ Right () ||| Checks whether an object would match a given `Prism` From 8c17a8b94c7698b6d04d17ee05bb601bed09afda Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 30 May 2022 13:23:20 +0200 Subject: [PATCH 053/126] Declare type of a and b --- src/Data/Const.idr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Const.idr b/src/Data/Const.idr index 03817d3..bfe5b32 100644 --- a/src/Data/Const.idr +++ b/src/Data/Const.idr @@ -3,7 +3,7 @@ module Data.Const %default total public export -record Const a b where +record Const (a, b : Type) where constructor MkConst runConst : a From a02673b6e6ced441cd3ff77631aeef3dda47903e Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 31 May 2022 12:30:02 +0200 Subject: [PATCH 054/126] Add mirror to imports --- src/Data/Profunctor/Choice.idr | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Data/Profunctor/Choice.idr b/src/Data/Profunctor/Choice.idr index 0f4c070..168a591 100644 --- a/src/Data/Profunctor/Choice.idr +++ b/src/Data/Profunctor/Choice.idr @@ -1,9 +1,10 @@ module Data.Profunctor.Choice +import Data.Either +import Data.Morphisms import Data.Profunctor -import Control.Category import Control.Arrow -import Data.Morphisms +import Control.Category %default total From b47b5710c8f7f81c320c0290e6e0d9236a0ce676 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 31 May 2022 12:30:25 +0200 Subject: [PATCH 055/126] Quantify Choice's type variable --- src/Data/Profunctor/Choice.idr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Profunctor/Choice.idr b/src/Data/Profunctor/Choice.idr index 168a591..113ecc0 100644 --- a/src/Data/Profunctor/Choice.idr +++ b/src/Data/Profunctor/Choice.idr @@ -14,7 +14,7 @@ import Control.Category ||| Generalized DownStar of a Costrong Functor public export -interface Profunctor p => Choice (p : Type -> Type -> Type) where +interface Profunctor p => Choice (0 p : Type -> Type -> Type) where ||| Like first' but with sum rather than product types ||| ||| ````idris example From cee02bdc41ed56ec5ace031020a6d00ff76f26f2 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 31 May 2022 12:32:42 +0200 Subject: [PATCH 056/126] Quantify Strong's type variable --- src/Data/Profunctor/Strong.idr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Profunctor/Strong.idr b/src/Data/Profunctor/Strong.idr index 4ab3e4a..2c7849c 100644 --- a/src/Data/Profunctor/Strong.idr +++ b/src/Data/Profunctor/Strong.idr @@ -12,7 +12,7 @@ import Control.Arrow ||| Generalized UpStar of a Strong Functor public export -interface Profunctor p => Strong (p : Type -> Type -> Type) where +interface Profunctor p => Strong (0 p : Type -> Type -> Type) where ||| Create a new Profunctor of tuples with first element from the original ||| ||| ````idris example From 171e64f9e6022d6c933356637620ea1e85b04521 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 31 May 2022 12:35:32 +0200 Subject: [PATCH 057/126] Quantify Wander's type variable and f in wander --- src/Data/Profunctor/Wander.idr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Data/Profunctor/Wander.idr b/src/Data/Profunctor/Wander.idr index a56c2d0..04db4c1 100644 --- a/src/Data/Profunctor/Wander.idr +++ b/src/Data/Profunctor/Wander.idr @@ -11,8 +11,8 @@ import Data.Morphisms ||| Profunctors that support polymorphic traversals public export -interface (Strong p, Choice p) => Wander (p : Type -> Type -> Type) where - wander : ({f : Type -> Type} -> Applicative f => (a -> f b) -> s -> f t) -> p a b -> p s t +interface (Strong p, Choice p) => Wander (0 p : Type -> Type -> Type) where + wander : ({0 f : Type -> Type} -> Applicative f => (a -> f b) -> s -> f t) -> p a b -> p s t export Wander Morphism where From bc536dd72f663821af36e5cb36a7e2e99a9ef60e Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 31 May 2022 12:36:38 +0200 Subject: [PATCH 058/126] Remove %implementation qualifiers --- src/Data/Profunctor/Wander.idr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Data/Profunctor/Wander.idr b/src/Data/Profunctor/Wander.idr index 04db4c1..eb8ddd2 100644 --- a/src/Data/Profunctor/Wander.idr +++ b/src/Data/Profunctor/Wander.idr @@ -16,7 +16,7 @@ interface (Strong p, Choice p) => Wander (0 p : Type -> Type -> Type) where export Wander Morphism where - wander t (Mor f) = Mor $ runIdentity . t (%implementation) (Id . f) + wander t (Mor f) = Mor $ runIdentity . t (Id . f) export Applicative f => Wander (UpStarred f) where @@ -24,4 +24,4 @@ Applicative f => Wander (UpStarred f) where export Monoid r => Wander (Forgotten r) where - wander t (Forget r) = Forget $ runConst . t (%implementation) (MkConst . r) + wander t (Forget f) = Forget $ runConst . t (MkConst . f) From e689deb347b81cecfe8d650ded0628055a1ffb54 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 31 May 2022 12:36:55 +0200 Subject: [PATCH 059/126] Remove implicit Applicative instance --- src/Data/Profunctor/Wander.idr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Profunctor/Wander.idr b/src/Data/Profunctor/Wander.idr index eb8ddd2..ed0bf82 100644 --- a/src/Data/Profunctor/Wander.idr +++ b/src/Data/Profunctor/Wander.idr @@ -20,7 +20,7 @@ Wander Morphism where export Applicative f => Wander (UpStarred f) where - wander @{ap} t (UpStar f) = UpStar $ t ap f + wander t (UpStar u) = UpStar $ t u export Monoid r => Wander (Forgotten r) where From 4e5c60990e30d11b980bfc46f7cdb2ea9f5424f2 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 31 May 2022 12:39:01 +0200 Subject: [PATCH 060/126] Fix module name --- src/Data/Profunctor/Traversal.idr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Profunctor/Traversal.idr b/src/Data/Profunctor/Traversal.idr index d482cba..1b7761a 100644 --- a/src/Data/Profunctor/Traversal.idr +++ b/src/Data/Profunctor/Traversal.idr @@ -1,4 +1,4 @@ -module Data.Profunctor.Fold +module Data.Profunctor.Traversal import Data.Profunctor import Data.Profunctor.Wander From 1e2eddc0653f50160c3e834ae9a71c6b2a8cda42 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 31 May 2022 12:43:08 +0200 Subject: [PATCH 061/126] Remove import of Data.Bitraversable --- src/Data/Profunctor/Traversal.idr | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Data/Profunctor/Traversal.idr b/src/Data/Profunctor/Traversal.idr index 1b7761a..90c1647 100644 --- a/src/Data/Profunctor/Traversal.idr +++ b/src/Data/Profunctor/Traversal.idr @@ -1,10 +1,9 @@ module Data.Profunctor.Traversal +import Data.Morphisms import Data.Profunctor import Data.Profunctor.Wander import Data.Profunctor.Iso -import Data.Morphisms -import Data.Bitraversable import Control.Monad.Identity %default total From 9505fd6f20c1bda7182abf5b5856586860c8ff18 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 31 May 2022 12:44:38 +0200 Subject: [PATCH 062/126] Fix Wander type restriction in Traversal and Traversal' --- src/Data/Profunctor/Traversal.idr | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Data/Profunctor/Traversal.idr b/src/Data/Profunctor/Traversal.idr index 90c1647..8077b46 100644 --- a/src/Data/Profunctor/Traversal.idr +++ b/src/Data/Profunctor/Traversal.idr @@ -9,13 +9,13 @@ import Control.Monad.Identity %default total public export -Traversal : Wander p => Type -> Type -> Type -> Type -> Type -Traversal {p} = preIso {p} +Traversal : {p : Type -> Type -> Type} -> Type -> Type -> Type -> Type -> Type +Traversal s t a b = Wander p => preIso {p} s t a b ||| A Traversal that does not change types public export -Traversal' : Wander p => Type -> Type -> Type -Traversal' {p} = Simple $ Traversal {p} +Traversal' : {p : Type -> Type -> Type} -> Type -> Type -> Type +Traversal' s a = Simple (Traversal {p}) s a export traversed : (Wander p, Traversable t) => Traversal {p} (t a) (t b) a b From 954b40bcbb4853c4b86a46fe0287e2696544651a Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 31 May 2022 12:46:40 +0200 Subject: [PATCH 063/126] Remove Wander type restriction in traversed --- src/Data/Profunctor/Traversal.idr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Profunctor/Traversal.idr b/src/Data/Profunctor/Traversal.idr index 8077b46..c5265d5 100644 --- a/src/Data/Profunctor/Traversal.idr +++ b/src/Data/Profunctor/Traversal.idr @@ -18,7 +18,7 @@ Traversal' : {p : Type -> Type -> Type} -> Type -> Type -> Type Traversal' s a = Simple (Traversal {p}) s a export -traversed : (Wander p, Traversable t) => Traversal {p} (t a) (t b) a b +traversed : Traversable t => Traversal {p} (t a) (t b) a b traversed {t} = wander $ traverse {f=f1} {t} export From 8bdb7c97a91bbf1d95f887d7357ee534c96e8cb6 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 31 May 2022 12:47:32 +0200 Subject: [PATCH 064/126] Remove explicit implicit typing in traversed --- src/Data/Profunctor/Traversal.idr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Profunctor/Traversal.idr b/src/Data/Profunctor/Traversal.idr index c5265d5..331da3a 100644 --- a/src/Data/Profunctor/Traversal.idr +++ b/src/Data/Profunctor/Traversal.idr @@ -19,7 +19,7 @@ Traversal' s a = Simple (Traversal {p}) s a export traversed : Traversable t => Traversal {p} (t a) (t b) a b -traversed {t} = wander $ traverse {f=f1} {t} +traversed = wander $ traverse export both : Bitraversable r => Traversal {p=Morphism} (r a a) (r b b) a b From bc936c280cd9443291ceac3c4fa922a3e3fb1493 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 31 May 2022 12:48:08 +0200 Subject: [PATCH 065/126] Remove trailing whitespace --- src/Data/Profunctor/Traversal.idr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Profunctor/Traversal.idr b/src/Data/Profunctor/Traversal.idr index 331da3a..c4bd82a 100644 --- a/src/Data/Profunctor/Traversal.idr +++ b/src/Data/Profunctor/Traversal.idr @@ -23,4 +23,4 @@ traversed = wander $ traverse export both : Bitraversable r => Traversal {p=Morphism} (r a a) (r b b) a b -both (Mor f) = Mor $ runIdentity . bitraverse {f=Identity} (Id . f) (Id . f) +both (Mor f) = Mor $ runIdentity . bitraverse {f=Identity} (Id . f) (Id . f) From 657dc20d850cbeb89f55ef339461cfb896986f94 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 31 May 2022 12:57:26 +0200 Subject: [PATCH 066/126] Quantify Index' type variables --- src/Data/Profunctor/Traversal/Index.idr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Profunctor/Traversal/Index.idr b/src/Data/Profunctor/Traversal/Index.idr index 320aebe..14129e9 100644 --- a/src/Data/Profunctor/Traversal/Index.idr +++ b/src/Data/Profunctor/Traversal/Index.idr @@ -9,7 +9,7 @@ import Data.Profunctor.Traversal %default total public export -interface Wander p => Index (p : Type -> Type -> Type) (m : Type) (a : Type) (b : Type) | m where +interface Wander p => Index (0 p : Type -> Type -> Type) (0 m : Type) (0 a : Type) (0 b : Type) | m where ix : a -> Traversal' {p} m b export From 8bdb293077fa55c9ca37633854c4cce250b0d1b1 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 31 May 2022 12:58:00 +0200 Subject: [PATCH 067/126] Remove magical f1 implicits --- src/Data/Profunctor/Traversal/Index.idr | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Data/Profunctor/Traversal/Index.idr b/src/Data/Profunctor/Traversal/Index.idr index 14129e9..ca07166 100644 --- a/src/Data/Profunctor/Traversal/Index.idr +++ b/src/Data/Profunctor/Traversal/Index.idr @@ -18,10 +18,8 @@ Wander p => Index p (Maybe a) () a where export (Wander p, Ord k) => Index p (SortedMap k v) k v where - -- magical f1 - ix k = wander $ \coalg, m => maybe (pure {f=f1} m) (map {f=f1} (\v => insert k v m) . coalg) (lookup k m) + ix k = wander $ \coalg, m => maybe (pure m) (map (\v => insert k v m) . coalg) (lookup k m) export (Wander p, Ord a) => Index p (SortedSet a) a () where - -- magical f1 - ix x = wander $ \_ => pure {f=f1} . SortedSet.insert x + ix x = wander $ \_ => pure . SortedSet.insert x From 540f9dd71cca76d25f27bc920f1393dd87c17ce5 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 31 May 2022 12:59:38 +0200 Subject: [PATCH 068/126] Remove Wander type restrictions --- src/Data/Profunctor/Traversal/Index.idr | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Data/Profunctor/Traversal/Index.idr b/src/Data/Profunctor/Traversal/Index.idr index ca07166..6248e88 100644 --- a/src/Data/Profunctor/Traversal/Index.idr +++ b/src/Data/Profunctor/Traversal/Index.idr @@ -9,17 +9,17 @@ import Data.Profunctor.Traversal %default total public export -interface Wander p => Index (0 p : Type -> Type -> Type) (0 m : Type) (0 a : Type) (0 b : Type) | m where +interface Index (0 p : Type -> Type -> Type) (0 m : Type) (0 a : Type) (0 b : Type) | m where ix : a -> Traversal' {p} m b export -Wander p => Index p (Maybe a) () a where +Index p (Maybe a) () a where ix () = traversed export -(Wander p, Ord k) => Index p (SortedMap k v) k v where - ix k = wander $ \coalg, m => maybe (pure m) (map (\v => insert k v m) . coalg) (lookup k m) +Ord k => Index p (SortedMap k v) k v where + ix k = wander $ \coalg, m => maybe (pure m) (map (\v => insert k v m) . coalg) (lookup k m) export -(Wander p, Ord a) => Index p (SortedSet a) a () where - ix x = wander $ \_ => pure . SortedSet.insert x +Ord a => Index p (SortedSet a) a () where + ix x = wander $ \_ => pure . SortedSet.insert x From d645eea19f3e081861d09e8beda3e7c8865d9855 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 31 May 2022 12:59:58 +0200 Subject: [PATCH 069/126] Import Iso --- src/Data/Profunctor/Traversal/Index.idr | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Data/Profunctor/Traversal/Index.idr b/src/Data/Profunctor/Traversal/Index.idr index 6248e88..6459af5 100644 --- a/src/Data/Profunctor/Traversal/Index.idr +++ b/src/Data/Profunctor/Traversal/Index.idr @@ -3,8 +3,9 @@ module Data.Profunctor.Traversal.Index import Data.SortedMap import Data.SortedSet import Data.Profunctor -import Data.Profunctor.Wander +import Data.Profunctor.Iso import Data.Profunctor.Traversal +import Data.Profunctor.Wander %default total From 38f41f2432583d8239044ed3b3fa6f032a1088df Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 31 May 2022 13:02:15 +0200 Subject: [PATCH 070/126] Quantify At's type variables --- src/Data/Profunctor/Lens/At.idr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Profunctor/Lens/At.idr b/src/Data/Profunctor/Lens/At.idr index 2549f46..eb96a5e 100644 --- a/src/Data/Profunctor/Lens/At.idr +++ b/src/Data/Profunctor/Lens/At.idr @@ -12,7 +12,7 @@ import Data.Profunctor.Traversal.Index ||| Allows adding and deleting elements from "container-like" types public export -interface (Lensing p, Index p m a b) => At (p : Type -> Type -> Type) (m : Type) (a : Type) (b : Type) | m where +interface (Lensing p, Index p m a b) => At (0 p : Type -> Type -> Type) (0 m : Type) (0 a : Type) (0 b : Type) | m where at : a -> Lens' {p} m (Maybe b) export From aa460103ada0626d7aae8570cb89ae4dcc11c3c8 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 31 May 2022 13:04:57 +0200 Subject: [PATCH 071/126] Remove Lensing type restrictions --- src/Data/Profunctor/Lens/At.idr | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Data/Profunctor/Lens/At.idr b/src/Data/Profunctor/Lens/At.idr index eb96a5e..11c36fc 100644 --- a/src/Data/Profunctor/Lens/At.idr +++ b/src/Data/Profunctor/Lens/At.idr @@ -12,19 +12,19 @@ import Data.Profunctor.Traversal.Index ||| Allows adding and deleting elements from "container-like" types public export -interface (Lensing p, Index p m a b) => At (0 p : Type -> Type -> Type) (0 m : Type) (0 a : Type) (0 b : Type) | m where +interface Index p m a b => At (0 p : Type -> Type -> Type) (0 m : Type) (0 a : Type) (0 b : Type) | m where at : a -> Lens' {p} m (Maybe b) export -(Wander p, Lensing p) => At p (Maybe a) () a where - at () = id +At p (Maybe a) () a where + at () = id export -(Wander p, Lensing p, Ord k) => At p (SortedMap k v) k v where +Ord k => At p (SortedMap k v) k v where at k = lens (lookup k) (\m => maybe (delete k m) (\v => insert k v m)) export -(Wander p, Lensing p, Ord a) => At p (SortedSet a) a () where +Ord a => At p (SortedSet a) a () where at x = lens get (flip update) where get xs = if contains x xs then Just () else Nothing From a43003375256c6821da8d9f6c58236556f05cd92 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 31 May 2022 13:08:56 +0200 Subject: [PATCH 072/126] Add type declarations for functions in where clause --- src/Data/Profunctor/Lens/At.idr | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Data/Profunctor/Lens/At.idr b/src/Data/Profunctor/Lens/At.idr index 11c36fc..bae6381 100644 --- a/src/Data/Profunctor/Lens/At.idr +++ b/src/Data/Profunctor/Lens/At.idr @@ -27,9 +27,11 @@ export Ord a => At p (SortedSet a) a () where at x = lens get (flip update) where + get : SortedSet a -> Maybe () get xs = if contains x xs then Just () else Nothing + update : Maybe () -> SortedSet a -> SortedSet a update Nothing = delete x - update (Just _) = insert x + update (Just _) = insert x export sans : At Morphism m a b => a -> m -> m From c778ffef71ab6d3a746bd8c6083ddbb19d7e93eb Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 31 May 2022 13:09:44 +0200 Subject: [PATCH 073/126] Import Iso --- src/Data/Profunctor/Lens/At.idr | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Data/Profunctor/Lens/At.idr b/src/Data/Profunctor/Lens/At.idr index bae6381..3cbca20 100644 --- a/src/Data/Profunctor/Lens/At.idr +++ b/src/Data/Profunctor/Lens/At.idr @@ -4,9 +4,10 @@ import Data.Morphisms import Data.SortedMap import Data.SortedSet import Data.Profunctor -import Data.Profunctor.Wander +import Data.Profunctor.Iso import Data.Profunctor.Lens import Data.Profunctor.Traversal.Index +import Data.Profunctor.Wander %default total From 6743f611c7582b34c9659baa494e14bfc8521288 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 31 May 2022 13:15:21 +0200 Subject: [PATCH 074/126] Remove bifunctors dependeny --- profunctors.ipkg | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/profunctors.ipkg b/profunctors.ipkg index 9e45f68..3a8738f 100644 --- a/profunctors.ipkg +++ b/profunctors.ipkg @@ -4,7 +4,7 @@ sourcedir = "src" modules = Data.Profunctor , Data.Profunctor.Cayley - , Data.Profunctor.Choice + , Data.Profunctor.Choice , Data.Profunctor.Closed , Data.Profunctor.Codensity , Data.Profunctor.Composition @@ -20,6 +20,4 @@ modules = Data.Profunctor , Data.Profunctor.Traversal.Index , Data.Verified.Profunctor -pkgs = bifunctors - opts = "-p contrib" From 18f441e1cd70af8eddf8ba2e13ef396eecdbba72 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 31 May 2022 13:22:31 +0200 Subject: [PATCH 075/126] Erase x in closed --- src/Data/Profunctor/Closed.idr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Profunctor/Closed.idr b/src/Data/Profunctor/Closed.idr index 4a6b028..eea4a7f 100644 --- a/src/Data/Profunctor/Closed.idr +++ b/src/Data/Profunctor/Closed.idr @@ -16,7 +16,7 @@ interface Profunctor p => Closed (0 p : Type -> Type -> Type) where ||| closed $ DownStar $ show ||| ```` ||| - closed : {x : _} -> p a b -> p (x -> a) (x -> b) + closed : {0 x : _} -> p a b -> p (x -> a) (x -> b) export implementation Closed Morphism where From aaee4e0b1a80592aa1a2cd1b90e1105146d0ddad Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 31 May 2022 14:35:34 +0200 Subject: [PATCH 076/126] Fix Closed type restrictions --- src/Data/Profunctor/Grate.idr | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Data/Profunctor/Grate.idr b/src/Data/Profunctor/Grate.idr index d06f864..bed7e43 100644 --- a/src/Data/Profunctor/Grate.idr +++ b/src/Data/Profunctor/Grate.idr @@ -6,12 +6,12 @@ import Data.Profunctor.Closed import Data.Profunctor.Iso public export -Grate : Closed p => Type -> Type -> Type -> Type -> Type -Grate {p} = preIso {p} +Grate : {p : Type -> Type -> Type} -> Type -> Type -> Type -> Type -> Type +Grate s t a b = Closed p => preIso {p} s t a b public export -Grate' : Closed p => Type -> Type -> Type -Grate' {p} = Simple $ Grate {p} +Grate' : {p : Type -> Type -> Type} -> Type -> Type -> Type +Grate' s a = Simple (Grate {p}) s a export grate : (((s -> a) -> b) -> t) -> Grate {p=Morphism} s t a b From 452337d376d07bf6dffb440a6ae970c9ea0aa719 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 31 May 2022 14:38:21 +0200 Subject: [PATCH 077/126] Remove import of inexistent Monad module --- src/Data/Profunctor/Ran.idr | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Data/Profunctor/Ran.idr b/src/Data/Profunctor/Ran.idr index a0bd87b..60f32c3 100644 --- a/src/Data/Profunctor/Ran.idr +++ b/src/Data/Profunctor/Ran.idr @@ -2,7 +2,6 @@ module Data.Profunctor.Ran import Data.Profunctor import Data.Profunctor.Composition -import Data.Profunctor.Monad ||| The right Kan extension of a profunctor public export From c64c4944bf94db46b0dc9a5336712f2d84b80bb5 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Tue, 31 May 2022 14:38:40 +0200 Subject: [PATCH 078/126] Finish implementation of Ran record --- src/Data/Profunctor/Ran.idr | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Data/Profunctor/Ran.idr b/src/Data/Profunctor/Ran.idr index 60f32c3..3459740 100644 --- a/src/Data/Profunctor/Ran.idr +++ b/src/Data/Profunctor/Ran.idr @@ -5,9 +5,11 @@ import Data.Profunctor.Composition ||| The right Kan extension of a profunctor public export -record Ran : (Type -> Type -> Type) -> (Type -> Type -> Type) -> - Type -> Type -> Type where - Run : {x : _} -> (runRan : p x a -> q x b) -> Ran p q a b +record Ran (p : Type -> Type -> Type) (q : Type -> Type -> Type) + (a : Type) (b : Type) where + -- Run : {x : _} -> (runRan : p x a -> q x b) -> Ran p q a b + constructor Run + runRan : p x a -> q x b export implementation (Profunctor p, Profunctor q) => Profunctor (Ran p q) where From 652bf5a35b86e4c18c6318761b34d9386a0fbca3 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 27 Jun 2022 14:29:12 +0200 Subject: [PATCH 079/126] Fix curryRan implementation --- src/Data/Profunctor/Ran.idr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Data/Profunctor/Ran.idr b/src/Data/Profunctor/Ran.idr index 3459740..d274d60 100644 --- a/src/Data/Profunctor/Ran.idr +++ b/src/Data/Profunctor/Ran.idr @@ -23,5 +23,5 @@ implementation Profunctor q => Functor (Ran p q a) where ||| Split up composed Profunctors by putting a Ran in the middle export -curryRan : (Procomposed p q -/-> r) -> p -/-> Ran q r -curryRan f a b p = Run $ \q => f a b $ Procompose p q +curryRan : (Procomposed p q a b -> r a b) -> p a b -> Ran q r a b +curryRan fpro pab = Run $ \qaa => fpro (Procompose pab qaa) From 3bf7ba3a905096770901ced5a26105ca6d6145bd Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 27 Jun 2022 14:38:44 +0200 Subject: [PATCH 080/126] Move docstrings of constructors to record docs --- src/Data/Profunctor/Cayley.idr | 6 +++--- src/Data/Profunctor/Closed.idr | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Data/Profunctor/Cayley.idr b/src/Data/Profunctor/Cayley.idr index 6b8fb63..2cf1cb3 100644 --- a/src/Data/Profunctor/Cayley.idr +++ b/src/Data/Profunctor/Cayley.idr @@ -8,11 +8,11 @@ import Data.Profunctor.Choice import Data.Profunctor.Unsafe ||| Converts Monads on standard types to Monads on Profunctors +||| ````idris example +||| Cayley $ Just $ Kleisli $ \x => Just $ reverse x +||| ```` public export record Cayleyed (f : Type -> Type) (p : Type -> Type -> Type) a b where - ||| ````idris example - ||| Cayley $ Just $ Kleisli $ \x => Just $ reverse x - ||| ```` constructor Cayley runCayley : f (p a b) diff --git a/src/Data/Profunctor/Closed.idr b/src/Data/Profunctor/Closed.idr index eea4a7f..32266f8 100644 --- a/src/Data/Profunctor/Closed.idr +++ b/src/Data/Profunctor/Closed.idr @@ -35,14 +35,14 @@ implementation Closed Zipping where closed (MkZipping f) = MkZipping $ \f1, f2, x => f (f1 x) (f2 x) ||| Closure adjoins a Closed structure to any Profunctor +||| Adjoin a closed-structured Profunctor to a profunctor +||| +||| ````idris example +||| Close $ closed $ DownStar $ show +||| ```` +||| public export record Closure (p : Type -> Type -> Type) a b where - ||| Adjoin a closed-structured Profunctor to a profunctor - ||| - ||| ````idris example - ||| Close $ closed $ DownStar $ show - ||| ```` - ||| constructor Close runClosure : p (x -> a) (x -> b) From 54c043123262dd8c3d109da30320bc1589624a57 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 27 Jun 2022 14:45:32 +0200 Subject: [PATCH 081/126] Fix Choice implementation of Klaislimorphism --- src/Data/Profunctor/Choice.idr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Profunctor/Choice.idr b/src/Data/Profunctor/Choice.idr index 113ecc0..0e4b72f 100644 --- a/src/Data/Profunctor/Choice.idr +++ b/src/Data/Profunctor/Choice.idr @@ -36,7 +36,7 @@ interface Profunctor p => Choice (0 p : Type -> Type -> Type) where export implementation Monad m => Choice (Kleislimorphism m) where left' f = Kleisli $ either (applyKleisli $ f >>> arrow Left) - (applyKleisli $ arrow id >>> arrow Right) + (applyKleisli {f=m} $ arrow id >>> arrow Right) right' f = Kleisli $ either (applyKleisli {f=m} $ arrow id >>> arrow Left) (applyKleisli $ f >>> arrow Right) From adb2bce479e58cc8842679bbefd54284a14d5a9f Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 27 Jun 2022 14:45:56 +0200 Subject: [PATCH 082/126] Quantify Prisming's type variable --- src/Data/Profunctor/Prism.idr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Profunctor/Prism.idr b/src/Data/Profunctor/Prism.idr index 2dee58c..dc23240 100644 --- a/src/Data/Profunctor/Prism.idr +++ b/src/Data/Profunctor/Prism.idr @@ -8,7 +8,7 @@ import Data.Profunctor.Iso ||| A `Choice` `Profunctor` that can be used in a `Prism` public export -interface Choice p => Prisming (p : Type -> Type -> Type) where +interface Choice p => Prisming (0 p : Type -> Type -> Type) where costrength : p a b -> p (Either b a) b costrength = rmap (either id id) . right' From 7cf6dc6b848fde5c525d8a4ccefad600f1648bd3 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Wed, 29 Jun 2022 13:51:08 +0200 Subject: [PATCH 083/126] Prepend lens accessors with an 'l' --- src/Data/Profunctor/Lens.idr | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Data/Profunctor/Lens.idr b/src/Data/Profunctor/Lens.idr index 7232a75..498183b 100644 --- a/src/Data/Profunctor/Lens.idr +++ b/src/Data/Profunctor/Lens.idr @@ -164,32 +164,32 @@ export ||| A Lens for the first element of a tuple export -_1 : Lens {p} (a, b) (x, b) a x -_1 = lens' $ \(a,b) => (flip MkPair b, a) +l_1 : Lens {p} (a, b) (x, b) a x +l_1 = lens' $ \(a,b) => (flip MkPair b, a) ||| A Lens for the second element of a tuple export -_2 : Lens {p} (b, a) (b, x) a x -_2 = lens' $ \(b,a) => (MkPair b, a) +l_2 : Lens {p} (b, a) (b, x) a x +l_2 = lens' $ \(b,a) => (MkPair b, a) ||| A Lens for the first element of a non-empty vector export -_vCons : Lens {p} (Vect (S n) a) (Vect (S n) b) +l_vCons : Lens {p} (Vect (S n) a) (Vect (S n) b) (a, Vect n a) (b, Vect n b) -_vCons = lens' $ \(x::xs) => (uncurry (::), (x,xs)) +l_vCons = lens' $ \(x::xs) => (uncurry (::), (x,xs)) ||| A Lens for the nth element of a big-enough vector export -_vNth : {m : Nat} -> (n : Fin (S m)) -> +l_vNth : {m : Nat} -> (n : Fin (S m)) -> Lens {p} (Vect (S m) a) (Vect (S m) b) (a, Vect m a) (b, Vect m b) -_vNth n = lens' $ \v => (uncurry $ insertAt n, (index n v, deleteAt n v)) +l_vNth n = lens' $ \v => (uncurry $ insertAt n, (index n v, deleteAt n v)) ||| A Lens for the nth element of a big-enough heterogenous vector export -_hVNth : (i : Fin (S l)) -> Lens {p} (HVect us) (HVect vs) +l_hVNth : (i : Fin (S l)) -> Lens {p} (HVect us) (HVect vs) (index i us, HVect (deleteAt i us)) (index i vs, HVect (deleteAt i vs)) -_hVNth n = lens' $ \v => +l_hVNth n = lens' $ \v => (believe_me . uncurry (insertAt' n), (index n v, deleteAt n v)) where insertAt' : (i : Fin (S k)) -> a -> HVect ws -> HVect (insertAt i a ws) insertAt' FZ y xs = y :: xs From 98300fae332b02523692f697a07d600574a0cb62 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Wed, 29 Jun 2022 13:56:29 +0200 Subject: [PATCH 084/126] Add implementation for Applicative liftA2 function --- src/Data/Profunctor/Fold.idr | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Data/Profunctor/Fold.idr b/src/Data/Profunctor/Fold.idr index 1d1ab18..1e6ceca 100644 --- a/src/Data/Profunctor/Fold.idr +++ b/src/Data/Profunctor/Fold.idr @@ -6,6 +6,9 @@ import Data.Profunctor.Choice import Data.Profunctor.Prism import Data.SortedSet +liftA2 : Applicative f => (a -> b -> c) -> f a -> f b -> f c +liftA2 f x y = f <$> x <*> y + ||| A leftwards fold public export data L a b = MkL (r -> b) (r -> a -> r) r From 8e83ed5429f4d9e806e3f23152dd5c2b306838c1 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Wed, 29 Jun 2022 13:58:24 +0200 Subject: [PATCH 085/126] Fix scanR function --- src/Data/Profunctor/Fold.idr | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Data/Profunctor/Fold.idr b/src/Data/Profunctor/Fold.idr index 1e6ceca..23f051c 100644 --- a/src/Data/Profunctor/Fold.idr +++ b/src/Data/Profunctor/Fold.idr @@ -222,9 +222,10 @@ runR (MkR k h z) = k . foldr h z ||| Run an `R` on a `Foldable` container, accumulating results export -scanR : R a b -> List a -> List b -scanR (MkR k h z) = map k . scan' where - scan' [] = pure z +scanR : {r : Type} -> R a b -> List a -> List b +scanR (MkR {r} k h z) = map k . scan' where + scan' : List a -> List r + scan' [] = z :: [] scan' (x::xs) = let l = scan' xs in h x (case l of [] => z; (q::_) => q) :: l export From 7e785af1a3a609365ceba35ce761dc6f864d06bd Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Wed, 29 Jun 2022 14:04:01 +0200 Subject: [PATCH 086/126] Add type annotations for step functions --- src/Data/Profunctor/Fold.idr | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Data/Profunctor/Fold.idr b/src/Data/Profunctor/Fold.idr index 23f051c..f44fdcf 100644 --- a/src/Data/Profunctor/Fold.idr +++ b/src/Data/Profunctor/Fold.idr @@ -129,6 +129,7 @@ null = MkL id (const $ const False) True export find : (a -> Bool) -> L a (Maybe a) find p = MkL id step Nothing where + step : Maybe a -> a -> Maybe a step x a = case x of Nothing => if p a then Just a else Nothing _ => x @@ -136,6 +137,7 @@ find p = MkL id step Nothing where export index : Nat -> L a (Maybe a) index i = MkL done step (Left 0) where + step : Either Nat a -> a -> Either Nat a step x = case x of Left j => if i == j then Right else const . Left $ S j _ => const x done : Either Nat a -> Maybe a From bbc78e2f7e834308cb484e6d9f3fb5ad876d0d68 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Wed, 29 Jun 2022 14:06:08 +0200 Subject: [PATCH 087/126] Remove redundant Ord type restriction --- src/Data/Profunctor/Fold.idr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Profunctor/Fold.idr b/src/Data/Profunctor/Fold.idr index f44fdcf..f797e95 100644 --- a/src/Data/Profunctor/Fold.idr +++ b/src/Data/Profunctor/Fold.idr @@ -162,7 +162,7 @@ fastNub {a} = MkL (flip snd $ the (List a) []) export sort : Ord a => L a (List a) sort = MkL id (flip $ merge . pure) [] where - merge : Ord a => List a -> List a -> List a + merge : List a -> List a -> List a merge xs [] = xs merge [] ys = ys merge (x :: xs) (y :: ys) = if x < y then x :: merge xs (y :: ys) From 567bd88d11e857cf7a2808100ca8195d83ea916c Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Wed, 29 Jun 2022 14:07:10 +0200 Subject: [PATCH 088/126] Add laziness type annotations and fix lambdas --- src/Data/Profunctor/Fold.idr | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Data/Profunctor/Fold.idr b/src/Data/Profunctor/Fold.idr index f797e95..67f3b37 100644 --- a/src/Data/Profunctor/Fold.idr +++ b/src/Data/Profunctor/Fold.idr @@ -175,23 +175,23 @@ L1 s = MkL (\x => Delay x) (\m => Just . case m of Just x => s x; _ => id) Nothi ||| Returns the first element of its input, if it exists export -first : L a (Maybe a) -first = map (x => Force x) $ L1 const +first : L a (Lazy (Maybe a)) +first = map (\x => Force x) $ L1 const ||| Returns the last element of its input, if it exists export -last : L a (Maybe a) -last = map (x => Force x) . L1 $ flip const +last : L a (Lazy (Maybe a)) +last = map (\x => Force x) . L1 $ flip const ||| Returns the maximum element of its input, if it exists export -maximum : Ord a => L a (Maybe a) -maximum = map (x => Force x) $ L1 max +maximum : Ord a => L a (Lazy (Maybe a)) +maximum = map (\x => Force x) $ L1 max ||| Returns the minimum element of its input, if it exists export -minimum : Ord a => L a (Maybe a) -minimum = map (x => Force x) $ L1 min +minimum : Ord a => L a (Lazy (Maybe a)) +minimum = map (\x => Force x) $ L1 min ||| Sums the elements of its input export From e394f4e7912e5bea5bb6938f4e55d97e57783fac Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Wed, 29 Jun 2022 14:09:34 +0200 Subject: [PATCH 089/126] Use liftA2 function --- src/Data/Profunctor/Fold.idr | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Data/Profunctor/Fold.idr b/src/Data/Profunctor/Fold.idr index 67f3b37..29bb2a7 100644 --- a/src/Data/Profunctor/Fold.idr +++ b/src/Data/Profunctor/Fold.idr @@ -76,7 +76,7 @@ implementation Monad (L a) where export implementation Semigroup m => Semigroup (L a m) where - x <+> y = (<+>) <$> x <*> y + (<+>) = liftA2 (<+>) export implementation Monoid m => Monoid (L a m) where @@ -91,7 +91,7 @@ implementation AbelianGroup m => AbelianGroup (L a m) where export implementation Ring m => Ring (L a m) where - x <.> y = (<.>) <$> x <*> y + (<.>) = liftA2 (<.>) export implementation RingWithUnity m => RingWithUnity (L a m) where @@ -101,13 +101,13 @@ implementation RingWithUnity m => RingWithUnity (L a m) where export implementation Num n => Num (L a n) where - x + y = (+) <$> x <*> y - x * y = (*) <$> x <*> y + (+) = liftA2 (+) + (*) = liftA2 (*) fromInteger = pure . fromInteger export implementation Neg n => Neg (L a n) where - x - y = (-) <$> x <*> y + (-) = liftA2 (-) negate = map negate export @@ -276,7 +276,7 @@ implementation Monad (R a) where export implementation Semigroup m => Semigroup (R a m) where - x <+> y = (<+>) <$> x <*> y + (<+>) = liftA2 (<+>) export implementation Monoid m => Monoid (R a m) where @@ -284,13 +284,13 @@ implementation Monoid m => Monoid (R a m) where export implementation Num n => Num (R a n) where - x + y = (+) <$> x <*> y - x * y = (*) <$> x <*> y + (+) = liftA2 (+) + (*) = liftA2 (*) fromInteger = pure . fromInteger export implementation Neg n => Neg (R a n) where - x - y = (-) <$> x <*> y + (-) = liftA2 (-) negate = map negate export @@ -306,7 +306,7 @@ implementation AbelianGroup m => AbelianGroup (R a m) where export implementation Ring m => Ring (R a m) where - x <.> y = (<.>) <$> x <*> y + (<.>) = liftA2 (<.>) export implementation RingWithUnity m => RingWithUnity (R a m) where From c3d889fc93c114b5693ca7a0551f1480ee4de125 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Wed, 29 Jun 2022 14:12:38 +0200 Subject: [PATCH 090/126] Add holes for missing proofs --- src/Data/Profunctor/Fold.idr | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/Data/Profunctor/Fold.idr b/src/Data/Profunctor/Fold.idr index 29bb2a7..e6bf16a 100644 --- a/src/Data/Profunctor/Fold.idr +++ b/src/Data/Profunctor/Fold.idr @@ -78,24 +78,40 @@ export implementation Semigroup m => Semigroup (L a m) where (<+>) = liftA2 (<+>) +export +implementation SemigroupV m => SemigroupV (L a m) where + semigroupOpIsAssociative = ?holeSemigroupL + export implementation Monoid m => Monoid (L a m) where neutral = pure neutral +export +implementation MonoidV m => MonoidV (L a m) where + monoidNeutralIsNeutralL = ?holeMonoidLL + monoidNeutralIsNeutralR = ?holeMonoidLR + export implementation Group m => Group (L a m) where inverse = map inverse + groupInverseIsInverseR = ?holeGroupL export implementation AbelianGroup m => AbelianGroup (L a m) where + groupOpIsCommutative = ?abelianGroupHoleL export implementation Ring m => Ring (L a m) where (<.>) = liftA2 (<.>) + ringOpIsAssociative = ?holeRingAssocL + ringOpIsDistributiveL = ?holeRingDistrLL + ringOpIsDistributiveR = ?holeRingDistrLR export implementation RingWithUnity m => RingWithUnity (L a m) where unity = pure unity + unityIsRingIdL = ?holeRingUnityLL + unityIsRingIdR = ?holeRingUnityLR -- The `Field` implementation won't type check, but it should exist @@ -278,10 +294,19 @@ export implementation Semigroup m => Semigroup (R a m) where (<+>) = liftA2 (<+>) +export +implementation SemigroupV m => SemigroupV (R a m) where + semigroupOpIsAssociative = ?holeSemigroupR + export implementation Monoid m => Monoid (R a m) where neutral = pure neutral +export +implementation MonoidV m => MonoidV (R a m) where + monoidNeutralIsNeutralL = ?holeMonoidRL + monoidNeutralIsNeutralR = ?holeMonoidRR + export implementation Num n => Num (R a n) where (+) = liftA2 (+) @@ -300,17 +325,24 @@ implementation Abs n => Abs (R a n) where export implementation Group m => Group (R a m) where inverse = map inverse + groupInverseIsInverseR = ?holeGroupR export implementation AbelianGroup m => AbelianGroup (R a m) where + groupOpIsCommutative = ?holeAbelianCommR export implementation Ring m => Ring (R a m) where (<.>) = liftA2 (<.>) + ringOpIsAssociative = ?holeRingAssocR + ringOpIsDistributiveL = ?holeRingDistrRL + ringOpIsDistributiveR = ?holeRingDistrRR export implementation RingWithUnity m => RingWithUnity (R a m) where unity = pure unity + unityIsRingIdL = ?holeRingUnityRL + unityIsRingIdR = ?holeRingUnityRR ||| Convert an `L` to an `R` export From d4c884fee839da422c3c625eaa4d687b3b7b47fa Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Wed, 29 Jun 2022 14:15:44 +0200 Subject: [PATCH 091/126] Update readme to idris2 --- README.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e52efd1..57f08a3 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -Idris Profunctors -================= +Idris2 Profunctors +================== -This is a profunctor library for idris based off the excellent [Haskell Profunctors](https://github.com/ekmett/profunctors) package from Edward Kmett. Contributions, bug reports, and feature requests are welcome. +This is a profunctor library for Idris2 based off the excellent [Haskell Profunctors](https://github.com/ekmett/profunctors) package from Edward Kmett. Contributions, bug reports, and feature requests are welcome. Contains -------- @@ -16,9 +16,14 @@ Contains * Prisms +Misses +------ + + * Proofs for algebraic properties of Folds. + Installation ------------ -Run `idris --install profunctors.ipkg` from inside this directory, and then if +Run `idris2 --install profunctors.ipkg` from inside this directory, and then if you want to use it with anything, invoke idris with `-p profunctors` (i.e. -`idris -p profunctors hack_the_planet.idr`) +`idris2 -p profunctors hack_the_planet.idr`) From 61d227362fdedb01467cd97ba33abb4b2060f205 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Thu, 30 Jun 2022 15:00:12 +0200 Subject: [PATCH 092/126] Use Const provided by base --- src/Data/Const.idr | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/src/Data/Const.idr b/src/Data/Const.idr index bfe5b32..f1c3f25 100644 --- a/src/Data/Const.idr +++ b/src/Data/Const.idr @@ -1,26 +1,14 @@ module Data.Const -%default total - -public export -record Const (a, b : Type) where - constructor MkConst - runConst : a +import Control.Applicative.Const -export -Functor (Const m) where - map _ (MkConst v) = MkConst v +%default total export Monoid m => Applicative (Const m) where pure _ = MkConst neutral (MkConst a) <*> (MkConst b) = MkConst (a <+> b) -export -Foldable (Const a) where - foldr _ x _ = x - foldl _ x _ = x - export Traversable (Const a) where traverse _ (MkConst x) = pure $ MkConst x From 4b061e2b7e8d5210248801c7f7a616300b46713f Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Fri, 1 Jul 2022 12:03:09 +0200 Subject: [PATCH 093/126] Add Sieve module and interface --- src/Data/Profunctor/Composition.idr | 5 +++++ src/Data/Profunctor/Sieve.idr | 28 ++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 src/Data/Profunctor/Sieve.idr diff --git a/src/Data/Profunctor/Composition.idr b/src/Data/Profunctor/Composition.idr index 51fc084..a88cbf1 100644 --- a/src/Data/Profunctor/Composition.idr +++ b/src/Data/Profunctor/Composition.idr @@ -4,6 +4,7 @@ import Control.Arrow import Control.Category import Data.Profunctor import Data.Profunctor.Closed +import Data.Profunctor.Sieve ||| The composition of two Profunctors public export @@ -26,6 +27,10 @@ export implementation Profunctor p => Functor (Procomposed p q a) where map k (Procompose f g) = Procompose (rmap k f) g +export +implementation (Sieve p f, Sieve q g) => Sieve (Procomposed p q) (g . f) using Functor.Compose where + sieve (Procompose g f) d = sieve g <$> sieve f d + ||| The right Kan lift of one Profunctor along another public export record Rifted (p : Type -> Type -> Type) (q : Type -> Type -> Type) a b where diff --git a/src/Data/Profunctor/Sieve.idr b/src/Data/Profunctor/Sieve.idr new file mode 100644 index 0000000..e8f51dd --- /dev/null +++ b/src/Data/Profunctor/Sieve.idr @@ -0,0 +1,28 @@ +module Data.Profunctor.Sieve + +import Control.Applicative.Const +import Control.Monad.Identity +import Data.Morphisms + +import Data.Profunctor + +public export +interface (Profunctor p, Functor f) => Sieve p f where + sieve : p a b -> a -> f b + +export +implementation Sieve Morphism Identity where + sieve f = Id . applyMor f + +export +implementation (Monad m, Functor m) => Sieve (Kleislimorphism m) m where + sieve = applyKleisli + +export +implementation Functor f => Sieve (UpStarred f) f where + sieve = runUpStar + +export +implementation Sieve (Forgotten r) (Const r) where + sieve = (MkConst .) . runForget + From 6a75b62ebab2685b3a99e8d338ba8b95e1560754 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Fri, 1 Jul 2022 12:36:39 +0200 Subject: [PATCH 094/126] Add Proxy record and implementations --- src/Data/Proxy.idr | 55 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 src/Data/Proxy.idr diff --git a/src/Data/Proxy.idr b/src/Data/Proxy.idr new file mode 100644 index 0000000..71fa181 --- /dev/null +++ b/src/Data/Proxy.idr @@ -0,0 +1,55 @@ +module Data.Proxy + +import Data.Contravariant + +public export +record Proxy (a : Type) where + constructor MkProxy + +export +implementation Eq (Proxy a) where + (==) _ _ = True + +export +implementation Ord (Proxy a) where + compare _ _ = EQ + +export +implementation Semigroup (Proxy a) where + (<+>) _ _ = MkProxy + +export +implementation Monoid (Proxy a) where + neutral = MkProxy + +export +implementation Functor Proxy where + map _ _ = MkProxy + +export +implementation Applicative Proxy where + pure _ = MkProxy + (<*>) _ _ = MkProxy + +export +implementation Monad Proxy where + (>>=) _ _ = MkProxy + join _ = MkProxy + +export +implementation Foldable Proxy where + foldr _ z _ = z + +export +implementation Traversable Proxy where + traverse _ _ = pure MkProxy + +export +implementation Alternative Proxy where + empty = MkProxy + (<|>) _ _ = MkProxy + +export +implementation Contravariant Proxy where + contramap _ _ = MkProxy + From 549ac43e25f5202549a3b54dccfa964e0bd75910 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Fri, 1 Jul 2022 12:42:42 +0200 Subject: [PATCH 095/126] Add Cosieve record and implementations --- src/Data/Profunctor/Composition.idr | 4 ++++ src/Data/Profunctor/Sieve.idr | 22 ++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/Data/Profunctor/Composition.idr b/src/Data/Profunctor/Composition.idr index a88cbf1..85bd258 100644 --- a/src/Data/Profunctor/Composition.idr +++ b/src/Data/Profunctor/Composition.idr @@ -31,6 +31,10 @@ export implementation (Sieve p f, Sieve q g) => Sieve (Procomposed p q) (g . f) using Functor.Compose where sieve (Procompose g f) d = sieve g <$> sieve f d +export +implementation (Cosieve p f, Cosieve q g) => Cosieve (Procomposed p q) (f . g) using Functor.Compose where + cosieve (Procompose g f) d = cosieve g $ cosieve f <$> d + ||| The right Kan lift of one Profunctor along another public export record Rifted (p : Type -> Type -> Type) (q : Type -> Type -> Type) a b where diff --git a/src/Data/Profunctor/Sieve.idr b/src/Data/Profunctor/Sieve.idr index e8f51dd..f38f5a9 100644 --- a/src/Data/Profunctor/Sieve.idr +++ b/src/Data/Profunctor/Sieve.idr @@ -5,6 +5,8 @@ import Control.Monad.Identity import Data.Morphisms import Data.Profunctor +import Data.Profunctor.Comonad +import Data.Proxy public export interface (Profunctor p, Functor f) => Sieve p f where @@ -26,3 +28,23 @@ export implementation Sieve (Forgotten r) (Const r) where sieve = (MkConst .) . runForget +public export +interface (Profunctor p, Functor f) => Cosieve p f where + cosieve : p a b -> f a -> b + +export +implementation Cosieve Morphism Identity where + cosieve m (Id a) = applyMor m a + +export +implementation Functor w => Cosieve (Cokleislimorphism w) w where + cosieve = runCokleisli + +export +implementation Cosieve Tagged Proxy where + cosieve (Tag a) _ = a + +export +implementation Functor f => Cosieve (DownStarred f) f where + cosieve = runDownStar + From 32f09cd62971c3c26652f6b11bd3c2fb4838e681 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Fri, 1 Jul 2022 13:16:26 +0200 Subject: [PATCH 096/126] Add Strong, Choice and Closed instance of Procomposition --- src/Data/Profunctor/Composition.idr | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/Data/Profunctor/Composition.idr b/src/Data/Profunctor/Composition.idr index 85bd258..9234751 100644 --- a/src/Data/Profunctor/Composition.idr +++ b/src/Data/Profunctor/Composition.idr @@ -4,7 +4,9 @@ import Control.Arrow import Control.Category import Data.Profunctor import Data.Profunctor.Closed +import Data.Profunctor.Choice import Data.Profunctor.Sieve +import Data.Profunctor.Strong ||| The composition of two Profunctors public export @@ -27,6 +29,20 @@ export implementation Profunctor p => Functor (Procomposed p q a) where map k (Procompose f g) = Procompose (rmap k f) g +export +implementation (Strong p, Strong q) => Strong (Procomposed p q) where + first' (Procompose x y) = Procompose (first' x) (first' y) + second' (Procompose x y) = Procompose (second' x) (second' y) + +export +implementation (Choice p, Choice q) => Choice (Procomposed p q) where + left' (Procompose x y) = Procompose (left' x) (left' y) + right' (Procompose x y) = Procompose (right' x) (right' y) + +export +implementation (Closed p, Closed q) => Closed (Procomposed p q) where + closed (Procompose x y) = Procompose (closed x) (closed y) + export implementation (Sieve p f, Sieve q g) => Sieve (Procomposed p q) (g . f) using Functor.Compose where sieve (Procompose g f) d = sieve g <$> sieve f d From f0fd9ea74b3ece2a90b3682d2e36f3ef664f9484 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Fri, 1 Jul 2022 13:17:29 +0200 Subject: [PATCH 097/126] Add Representable interface and implementations --- src/Data/Profunctor/Composition.idr | 5 +++++ src/Data/Profunctor/Rep.idr | 29 +++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 src/Data/Profunctor/Rep.idr diff --git a/src/Data/Profunctor/Composition.idr b/src/Data/Profunctor/Composition.idr index 9234751..d78a943 100644 --- a/src/Data/Profunctor/Composition.idr +++ b/src/Data/Profunctor/Composition.idr @@ -5,6 +5,7 @@ import Control.Category import Data.Profunctor import Data.Profunctor.Closed import Data.Profunctor.Choice +import Data.Profunctor.Rep import Data.Profunctor.Sieve import Data.Profunctor.Strong @@ -47,6 +48,10 @@ export implementation (Sieve p f, Sieve q g) => Sieve (Procomposed p q) (g . f) using Functor.Compose where sieve (Procompose g f) d = sieve g <$> sieve f d +export +implementation (Representable p f, Representable q g) => Representable (Procomposed p q) (g . f) using Functor.Compose where + tabulate f = Procompose (tabulate id) (tabulate f) + export implementation (Cosieve p f, Cosieve q g) => Cosieve (Procomposed p q) (f . g) using Functor.Compose where cosieve (Procompose g f) d = cosieve g $ cosieve f <$> d diff --git a/src/Data/Profunctor/Rep.idr b/src/Data/Profunctor/Rep.idr new file mode 100644 index 0000000..fd5a165 --- /dev/null +++ b/src/Data/Profunctor/Rep.idr @@ -0,0 +1,29 @@ +module Data.Profunctor.Rep + +import Control.Applicative.Const +import Control.Monad.Identity +import Data.Morphisms + +import Data.Profunctor +import Data.Profunctor.Sieve +import Data.Profunctor.Strong + +public export +interface (Sieve p q, Strong p) => Representable p q where + tabulate : (d -> q c) -> p d c + +export +implementation Representable Morphism Identity where + tabulate f = Mor $ runIdentity . f + +export +implementation (Monad m, Functor m) => Representable (Kleislimorphism m) m where + tabulate = Kleisli + +export +implementation Functor f => Representable (UpStarred f) f where + tabulate = UpStar + +export +implementation Representable (Forgotten r) (Const r) where + tabulate = Forget . (runConst .) From d6f3ba73b0bb47803cafa6e5b212ad7735f255ab Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Fri, 1 Jul 2022 13:17:53 +0200 Subject: [PATCH 098/126] Remove legacy implementation of Const --- src/Data/Const.idr | 14 -------------- src/Data/Profunctor/Wander.idr | 2 +- 2 files changed, 1 insertion(+), 15 deletions(-) delete mode 100644 src/Data/Const.idr diff --git a/src/Data/Const.idr b/src/Data/Const.idr deleted file mode 100644 index f1c3f25..0000000 --- a/src/Data/Const.idr +++ /dev/null @@ -1,14 +0,0 @@ -module Data.Const - -import Control.Applicative.Const - -%default total - -export -Monoid m => Applicative (Const m) where - pure _ = MkConst neutral - (MkConst a) <*> (MkConst b) = MkConst (a <+> b) - -export -Traversable (Const a) where - traverse _ (MkConst x) = pure $ MkConst x diff --git a/src/Data/Profunctor/Wander.idr b/src/Data/Profunctor/Wander.idr index ed0bf82..af87fee 100644 --- a/src/Data/Profunctor/Wander.idr +++ b/src/Data/Profunctor/Wander.idr @@ -1,7 +1,7 @@ module Data.Profunctor.Wander +import Control.Applicative.Const import Control.Monad.Identity -import Data.Const import Data.Profunctor import Data.Profunctor.Strong import Data.Profunctor.Choice From 9655d18b16af576cd2451163c9252ae6d9bf131a Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Fri, 1 Jul 2022 13:18:56 +0200 Subject: [PATCH 099/126] Update package description with new modules --- profunctors.ipkg | 2 ++ 1 file changed, 2 insertions(+) diff --git a/profunctors.ipkg b/profunctors.ipkg index 3a8738f..09e2772 100644 --- a/profunctors.ipkg +++ b/profunctors.ipkg @@ -14,6 +14,8 @@ modules = Data.Profunctor , Data.Profunctor.Lens , Data.Profunctor.Lens.At , Data.Profunctor.Prism + , Data.Profunctor.Rep + , Data.Profunctor.Sieve , Data.Profunctor.Strong , Data.Profunctor.Trace , Data.Profunctor.Traversal From ae4c4eb8cae0fe06e3b20fe6b10e7630765cd526 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 4 Jul 2022 11:27:15 +0200 Subject: [PATCH 100/126] Add useful functions for representables --- src/Data/Profunctor/Rep.idr | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/Data/Profunctor/Rep.idr b/src/Data/Profunctor/Rep.idr index fd5a165..7db14ec 100644 --- a/src/Data/Profunctor/Rep.idr +++ b/src/Data/Profunctor/Rep.idr @@ -5,6 +5,7 @@ import Control.Monad.Identity import Data.Morphisms import Data.Profunctor +import Data.Profunctor.Iso import Data.Profunctor.Sieve import Data.Profunctor.Strong @@ -27,3 +28,20 @@ implementation Functor f => Representable (UpStarred f) f where export implementation Representable (Forgotten r) (Const r) where tabulate = Forget . (runConst .) + +export +tabulated : (Representable p f, Representable q g) => Iso (d -> f c) (d' -> g c') (p d c) (q d' c') +tabulated = iso tabulate sieve + +export +firstRep : Representable p (Pair a) => p a b -> p (a, c) (b, c) +firstRep p = tabulate go + where go : (a, c) -> Pair a (Pair b c) + go (a, c) = (,c) <$> sieve p a + +export +secondRep : Representable p (Pair c) => p a b -> p (c, a) (c, b) +secondRep p = tabulate go + where go : (c, a) -> Pair c (Pair c b) + go (c, a) = (c,) <$> sieve p a + From 59c02b8830562d44ba78f2952f3d6c3e2529e124 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 4 Jul 2022 15:26:33 +0200 Subject: [PATCH 101/126] Update package module listing --- profunctors.ipkg | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/profunctors.ipkg b/profunctors.ipkg index 09e2772..9a14eed 100644 --- a/profunctors.ipkg +++ b/profunctors.ipkg @@ -14,12 +14,16 @@ modules = Data.Profunctor , Data.Profunctor.Lens , Data.Profunctor.Lens.At , Data.Profunctor.Prism + , Data.Profunctor.Ran , Data.Profunctor.Rep , Data.Profunctor.Sieve , Data.Profunctor.Strong , Data.Profunctor.Trace , Data.Profunctor.Traversal , Data.Profunctor.Traversal.Index + , Data.Profunctor.Unsafe + , Data.Profunctor.Wander + , Data.Proxy , Data.Verified.Profunctor opts = "-p contrib" From 15cd85267c8205a32d126b8eb79360f95fc21745 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Thu, 7 Jul 2022 09:59:49 +0200 Subject: [PATCH 102/126] Update package description to use comonad package --- profunctors.ipkg | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/profunctors.ipkg b/profunctors.ipkg index 9a14eed..2d6f2d2 100644 --- a/profunctors.ipkg +++ b/profunctors.ipkg @@ -8,6 +8,7 @@ modules = Data.Profunctor , Data.Profunctor.Closed , Data.Profunctor.Codensity , Data.Profunctor.Composition + , Data.Profunctor.Comonad , Data.Profunctor.Fold , Data.Profunctor.Grate , Data.Profunctor.Iso @@ -26,4 +27,6 @@ modules = Data.Profunctor , Data.Proxy , Data.Verified.Profunctor -opts = "-p contrib" +depends = comonad + +opts = "-p contrib comonad" From 894b48be8810091edc9c2a0a1afbb9590a13a4f6 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Thu, 7 Jul 2022 10:00:06 +0200 Subject: [PATCH 103/126] Remove redundant comonad definitions --- src/Data/Profunctor/Comonad.idr | 35 +-------------------------------- 1 file changed, 1 insertion(+), 34 deletions(-) diff --git a/src/Data/Profunctor/Comonad.idr b/src/Data/Profunctor/Comonad.idr index ee5e82c..6f6e933 100644 --- a/src/Data/Profunctor/Comonad.idr +++ b/src/Data/Profunctor/Comonad.idr @@ -2,47 +2,14 @@ module Data.Profunctor.Comonad import Control.Arrow import Control.Category +import Control.Comonad import Data.Profunctor -public export -interface Functor w => Comonad (0 w : Type -> Type) where - extract : w a -> a - - duplicate : w a -> w (w a) - duplicate = extend id - - extend : (w a -> b) -> w a -> w b - extend f = map f . duplicate - export implementation Comonad (Tagged a) where duplicate = Tag extract = runTagged -infixr 1 =>> -export -(=>>) : Comonad w => w a -> (w a -> b) -> w b -(=>>) = flip extend - -infixl 1 <<= -export -(<<=) : Comonad w => (w a -> b) -> w a -> w b -(<<=) = extend - -export -wfix : Comonad w => w (w a -> a) -> a -wfix w = extract w $ w =>> wfix - -infixr 1 =<= -export -(=<=) : Comonad w => (w b -> c) -> (w a -> b) -> w a -> c -f =<= g = f . extend g - -infixr 1 =>= -export -(=>=) : Comonad w => (w a -> b) -> (w b -> c) -> w a -> c -f =>= g = g . extend f - public export record Cokleislimorphism (w : Type -> Type) a b where constructor Cokleisli From b17a59d436f56ff29e1aa0e465096a8625076930 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Thu, 7 Jul 2022 12:22:35 +0200 Subject: [PATCH 104/126] Move Tagged comonad implementation to profunctor module --- src/Data/Profunctor.idr | 6 ++++++ src/Data/Profunctor/Comonad.idr | 5 ----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Data/Profunctor.idr b/src/Data/Profunctor.idr index 15e5eb1..5b44c70 100644 --- a/src/Data/Profunctor.idr +++ b/src/Data/Profunctor.idr @@ -3,6 +3,7 @@ module Data.Profunctor import Control.Monad.Identity import Control.Arrow import Control.Category +import Control.Comonad import Data.Either import Data.Morphisms @@ -62,6 +63,11 @@ export implementation Functor (Tagged a) where map = rmap +export +implementation Comonad (Tagged a) where + duplicate = Tag + extract = runTagged + -- UpStar -- {{{ diff --git a/src/Data/Profunctor/Comonad.idr b/src/Data/Profunctor/Comonad.idr index 6f6e933..24a8766 100644 --- a/src/Data/Profunctor/Comonad.idr +++ b/src/Data/Profunctor/Comonad.idr @@ -5,11 +5,6 @@ import Control.Category import Control.Comonad import Data.Profunctor -export -implementation Comonad (Tagged a) where - duplicate = Tag - extract = runTagged - public export record Cokleislimorphism (w : Type -> Type) a b where constructor Cokleisli From 29c4741a9f943a6cf582836051e80cea70c48b52 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Thu, 7 Jul 2022 12:22:47 +0200 Subject: [PATCH 105/126] Add Monad module --- profunctors.ipkg | 1 + src/Data/Profunctor/Monad.idr | 64 +++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 src/Data/Profunctor/Monad.idr diff --git a/profunctors.ipkg b/profunctors.ipkg index 2d6f2d2..fbf7c8f 100644 --- a/profunctors.ipkg +++ b/profunctors.ipkg @@ -14,6 +14,7 @@ modules = Data.Profunctor , Data.Profunctor.Iso , Data.Profunctor.Lens , Data.Profunctor.Lens.At + , Data.Profunctor.Monad , Data.Profunctor.Prism , Data.Profunctor.Ran , Data.Profunctor.Rep diff --git a/src/Data/Profunctor/Monad.idr b/src/Data/Profunctor/Monad.idr new file mode 100644 index 0000000..6b18415 --- /dev/null +++ b/src/Data/Profunctor/Monad.idr @@ -0,0 +1,64 @@ +module Data.Profunctor.Monad + +import Control.Category +import Control.Comonad + +import Data.Profunctor +import Data.Profunctor.Cayley +import Data.Profunctor.Closed +import Data.Profunctor.Composition +import Data.Profunctor.Ran + +public export +interface ProfunctorFunctor (0 t : (Type -> Type -> Type) -> Type -> Type -> Type) where + promap : (forall a, b. p a b -> q a b) -> t p a b -> t q a b + +export +implementation ProfunctorFunctor (Ran p) where + promap f (Run g) = Run (f . g) + +export +implementation ProfunctorFunctor (Rifted p) where + promap f (Rift g) = Rift (f . g) + +export +implementation ProfunctorFunctor Closure where + promap f (Close p) = Close (f p) + +export +implementation ProfunctorFunctor Environment where + promap f (Environize l m r) = Environize l (f m) r + +export +implementation Functor f => ProfunctorFunctor (Cayleyed f) where + promap f (Cayley p) = Cayley (f <$> p) + +export +implementation ProfunctorFunctor (Procomposed p) where + promap f (Procompose p q) = Procompose p (f q) + +public export +interface ProfunctorFunctor t => ProfunctorMonad t where + propure : Profunctor p => p a b -> t p a b + projoin : Profunctor p => t (t p) a b -> t p a b + +export +implementation Category p => ProfunctorMonad (Procomposed p) where + propure = Procompose id + projoin (Procompose p (Procompose q r)) = Procompose (p . q) r + +export +implementation (Functor f, Monad f) => ProfunctorMonad (Cayleyed f) where + propure = Cayley . pure + projoin (Cayley m) = Cayley $ m >>= runCayley + +public export +interface ProfunctorFunctor t => ProfunctorComonad t where + proextract : Profunctor p => t p a b -> p a b + produplicate : Profunctor p => t p a b -> t (t p) a b + +export +implementation Comonad f => ProfunctorComonad (Cayleyed f) where + proextract (Cayley f) = extract f + produplicate (Cayley p) = Cayley (Cayley <$> duplicate p) + From 5be1f5c458b8f60302ab68773ce30e86214ca2b4 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 31 Oct 2022 11:58:19 +0100 Subject: [PATCH 106/126] Add Fold interface and implementations --- src/Data/Profunctor/Fold.idr | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/Data/Profunctor/Fold.idr b/src/Data/Profunctor/Fold.idr index e6bf16a..908b7a4 100644 --- a/src/Data/Profunctor/Fold.idr +++ b/src/Data/Profunctor/Fold.idr @@ -9,6 +9,10 @@ import Data.SortedSet liftA2 : Applicative f => (a -> b -> c) -> f a -> f b -> f c liftA2 f x y = f <$> x <*> y +public export +interface Fold f where + run : Foldable t => f a b -> t a -> b + ||| A leftwards fold public export data L a b = MkL (r -> b) (r -> a -> r) r @@ -30,6 +34,10 @@ scanL : L a b -> List a -> List b scanL (MkL k _ z) [] = pure $ k z scanL (MkL k h z) (x::xs) = k (h z x) :: scanL (MkL k h (h z x)) xs +export +implementation Fold L where + run = runL + export implementation Profunctor L where dimap f g (MkL k h z) = MkL (g . k) ((. f) . h) z @@ -246,6 +254,10 @@ scanR (MkR {r} k h z) = map k . scan' where scan' [] = z :: [] scan' (x::xs) = let l = scan' xs in h x (case l of [] => z; (q::_) => q) :: l +export +implementation Fold R where + run = runR + export implementation Profunctor R where dimap f g (MkR k h z) = MkR (g . k) (h . f) z From 8cafa99e2414536f1b3da6ffb22b903b3c93d2aa Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 31 Oct 2022 13:14:38 +0100 Subject: [PATCH 107/126] Add foldable interface with verified toList instance --- src/Data/Verified/Foldable.idr | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/Data/Verified/Foldable.idr diff --git a/src/Data/Verified/Foldable.idr b/src/Data/Verified/Foldable.idr new file mode 100644 index 0000000..a89c284 --- /dev/null +++ b/src/Data/Verified/Foldable.idr @@ -0,0 +1,9 @@ +module Data.Verified.Foldable + +%default total + +public export +interface Foldable t => FoldableV t where + toListNeutralL : (f : r -> a -> r) -> (z : r) -> (fo : t a) -> foldl f z fo = foldl f z (Prelude.toList fo) + toListNeutralR : (f : a -> r -> r) -> (z : r) -> (fo : t a) -> foldr f z fo = foldr f z (Prelude.toList fo) + From ddae6875f67d3e69e086707f87b4633391230cff Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 31 Oct 2022 13:20:56 +0100 Subject: [PATCH 108/126] Add extensionality axiom for folds --- src/Data/Profunctor/Fold.idr | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Data/Profunctor/Fold.idr b/src/Data/Profunctor/Fold.idr index 908b7a4..d427a76 100644 --- a/src/Data/Profunctor/Fold.idr +++ b/src/Data/Profunctor/Fold.idr @@ -5,6 +5,7 @@ import Data.Profunctor import Data.Profunctor.Choice import Data.Profunctor.Prism import Data.SortedSet +import Data.Verified.Foldable liftA2 : Applicative f => (a -> b -> c) -> f a -> f b -> f c liftA2 f x y = f <$> x <*> y @@ -13,6 +14,11 @@ public export interface Fold f where run : Foldable t => f a b -> t a -> b + ||| Two folds are equal if they are point wise equal in their ``run`` function. + ||| We need this axiom because otherwise the Applicative instance would be unlawful. + ||| The requirement for a ``FoldableV`` instance stems from the necessity to destruct ``t``. + foldExtensionality : Fold f => (fa, fb : f a b) -> (forall t. FoldableV t => (l : t a) -> run fa l = run fb l) -> fa = fb + ||| A leftwards fold public export data L a b = MkL (r -> b) (r -> a -> r) r @@ -37,6 +43,7 @@ scanL (MkL k h z) (x::xs) = k (h z x) :: scanL (MkL k h (h z x)) xs export implementation Fold L where run = runL + foldExtensionality a b = believe_me export implementation Profunctor L where @@ -257,6 +264,7 @@ scanR (MkR {r} k h z) = map k . scan' where export implementation Fold R where run = runR + foldExtensionality a b = believe_me export implementation Profunctor R where From f47ef2bc0995c08fca19ed8ba28e25f219b86027 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 31 Oct 2022 13:33:10 +0100 Subject: [PATCH 109/126] Use named functions for Applicative instance --- src/Data/Profunctor/Fold.idr | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/Data/Profunctor/Fold.idr b/src/Data/Profunctor/Fold.idr index d427a76..257b156 100644 --- a/src/Data/Profunctor/Fold.idr +++ b/src/Data/Profunctor/Fold.idr @@ -19,6 +19,21 @@ interface Fold f where ||| The requirement for a ``FoldableV`` instance stems from the necessity to destruct ``t``. foldExtensionality : Fold f => (fa, fb : f a b) -> (forall t. FoldableV t => (l : t a) -> run fa l = run fb l) -> fa = fb +namespace Fold + public export + finish : (r1 -> a -> b) -> (r2 -> a) -> (r1, r2) -> b + finish f g (x, y) = f x (g y) + + namespace L + public export + step : (r1 -> a -> r1) -> (r2 -> a -> r2) -> (r1, r2) -> a -> (r1, r2) + step u v (x, y) b = (u x b, v y b) + + namespace R + public export + step : (a -> r1 -> r1) -> (a -> r2 -> r2) -> a -> (r1, r2) -> (r1, r2) + step u v b (x, y) = (u b x, v b y) + ||| A leftwards fold public export data L a b = MkL (r -> b) (r -> a -> r) r @@ -81,9 +96,7 @@ implementation Functor (L a) where export implementation Applicative (L a) where pure b = MkL (const b) (const $ const ()) () - (MkL f u y) <*> (MkL a v z) = MkL (uncurry $ (. a) . f) - (\(x, y), b => (u x b, v y b)) - (y, z) + (MkL f u y) <*> (MkL a v z) = MkL (Fold.finish f a) (Fold.L.step u v) (y, z) export implementation Monad (L a) where @@ -302,9 +315,7 @@ implementation Functor (R a) where export implementation Applicative (R a) where pure b = MkR (const b) (const $ const ()) () - (MkR f u y) <*> (MkR a v z) = MkR (uncurry $ (. a) . f) - (\b, (x, y) => (u b x, v b y)) - (y, z) + (MkR f u y) <*> (MkR a v z) = MkR (Fold.finish f a) (Fold.R.step u v) (y, z) export implementation Monad (R a) where From e7c87170d4929258f9fd0d62a3c18267962e6037 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 31 Oct 2022 13:37:01 +0100 Subject: [PATCH 110/126] Show distribution of run functions in semigroups --- src/Data/Profunctor/Fold.idr | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/Data/Profunctor/Fold.idr b/src/Data/Profunctor/Fold.idr index 257b156..f32d331 100644 --- a/src/Data/Profunctor/Fold.idr +++ b/src/Data/Profunctor/Fold.idr @@ -106,6 +106,17 @@ export implementation Semigroup m => Semigroup (L a m) where (<+>) = liftA2 (<+>) +public export +runLSemigroupDistributive : (FoldableV t, Semigroup m) => (ll, lr : L a m) -> (fo : t a) -> runL (ll <+> lr) fo = runL ll fo <+> runL lr fo +runLSemigroupDistributive (MkL {r=r1} d g u) (MkL {r=r2} e h v) fo = let + prf : (xs : List a) -> (u : r1) -> (v : r2) -> foldl (L.step g h) (u, v) xs = (foldl g u xs, foldl h v xs) + prf [] = \_, _ => Refl + prf (x::xs) = \y, z => prf xs (g y x) (h z x) + in rewrite toListNeutralL g u fo + in rewrite toListNeutralL h v fo + in rewrite toListNeutralL (step g h) (u, v) fo + in cong (Fold.finish (\n, m => d n <+> m) e) (prf (toList fo) u v) + export implementation SemigroupV m => SemigroupV (L a m) where semigroupOpIsAssociative = ?holeSemigroupL @@ -325,6 +336,17 @@ export implementation Semigroup m => Semigroup (R a m) where (<+>) = liftA2 (<+>) +public export +runRSemigroupDistributive : (FoldableV t, Semigroup m) => (rl, rr : R a m) -> (li : t a) -> runR (rl <+> rr) li = runR rl li <+> runR rr li +runRSemigroupDistributive (MkR {r=r1} d g u) (MkR {r=r2} e h v) fo = let + prf : (xs : List a) -> foldr (R.step g h) (u, v) xs = (foldr g u xs, foldr h v xs) + prf [] = Refl + prf (x::xs) = cong (step g h x) (prf xs) + in rewrite toListNeutralR g u fo + in rewrite toListNeutralR h v fo + in rewrite toListNeutralR (step g h) (u, v) fo + in cong (Fold.finish (\n, m => d n <+> m) e) (prf (toList fo)) + export implementation SemigroupV m => SemigroupV (R a m) where semigroupOpIsAssociative = ?holeSemigroupR From ef9c28db34ad00f49d3c42a7faa64d41b89779cf Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 31 Oct 2022 13:37:48 +0100 Subject: [PATCH 111/126] Show associativity of fold semigroup instances --- src/Data/Profunctor/Fold.idr | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/Data/Profunctor/Fold.idr b/src/Data/Profunctor/Fold.idr index f32d331..622b859 100644 --- a/src/Data/Profunctor/Fold.idr +++ b/src/Data/Profunctor/Fold.idr @@ -118,8 +118,16 @@ runLSemigroupDistributive (MkL {r=r1} d g u) (MkL {r=r2} e h v) fo = let in cong (Fold.finish (\n, m => d n <+> m) e) (prf (toList fo) u v) export -implementation SemigroupV m => SemigroupV (L a m) where - semigroupOpIsAssociative = ?holeSemigroupL +implementation (SemigroupV m) => SemigroupV (L a m) where + semigroupOpIsAssociative l@(MkL {r=r1} d g u) c@(MkL {r=r2} e h v) r@(MkL {r=r3} f j w) + = let + prf : forall t. FoldableV t => (fo : t a) -> runL (l <+> (c <+> r)) fo = runL ((l <+> c) <+> r) fo + prf fo = rewrite runLSemigroupDistributive l (c <+> r) fo + in rewrite runLSemigroupDistributive c r fo + in rewrite semigroupOpIsAssociative (d (foldl g u fo)) (e (foldl h v fo)) (f (foldl j w fo)) + in rewrite sym (runLSemigroupDistributive l c fo) + in sym (runLSemigroupDistributive (l <+> c) r fo) + in foldExtensionality (l <+> (c <+> r)) ((l <+> c) <+> r) prf export implementation Monoid m => Monoid (L a m) where @@ -349,7 +357,14 @@ runRSemigroupDistributive (MkR {r=r1} d g u) (MkR {r=r2} e h v) fo = let export implementation SemigroupV m => SemigroupV (R a m) where - semigroupOpIsAssociative = ?holeSemigroupR + semigroupOpIsAssociative l@(MkR d g u) c@(MkR e h v) r@(MkR f j w) = let + prf : forall t. FoldableV t => (fo : t a) -> runR (l <+> (c <+> r)) fo = runR ((l <+> c) <+> r) fo + prf fo = rewrite runRSemigroupDistributive l (c <+> r) fo + in rewrite runRSemigroupDistributive c r fo + in rewrite semigroupOpIsAssociative (d (foldr g u fo)) (e (foldr h v fo)) (f (foldr j w fo)) + in rewrite sym (runRSemigroupDistributive l c fo) + in sym (runRSemigroupDistributive (l <+> c) r fo) + in foldExtensionality (l <+> (c <+> r)) ((l <+> c) <+> r) prf export implementation Monoid m => Monoid (R a m) where From d3f5a24da2f246308e744da72246985e282b07af Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 31 Oct 2022 13:39:35 +0100 Subject: [PATCH 112/126] Show neutrality of neutral fold element --- src/Data/Profunctor/Fold.idr | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/src/Data/Profunctor/Fold.idr b/src/Data/Profunctor/Fold.idr index 622b859..2874487 100644 --- a/src/Data/Profunctor/Fold.idr +++ b/src/Data/Profunctor/Fold.idr @@ -135,8 +135,21 @@ implementation Monoid m => Monoid (L a m) where export implementation MonoidV m => MonoidV (L a m) where - monoidNeutralIsNeutralL = ?holeMonoidLL - monoidNeutralIsNeutralR = ?holeMonoidLR + monoidNeutralIsNeutralL l@(MkL k h z) = let + neut : L a m + neut = neutral + prf : forall t. FoldableV t => (fo : t a) -> runL (l <+> neut) fo = runL l fo + prf fo = rewrite runLSemigroupDistributive l neut fo + in monoidNeutralIsNeutralL (k (foldl h z fo)) + + in foldExtensionality (l <+> neut) l prf + monoidNeutralIsNeutralR l@(MkL k h z) = let + neut : L a m + neut = neutral + prf : forall t. FoldableV t => (fo : t a) -> runL (neut <+> l) fo = runL l fo + prf fo = rewrite runLSemigroupDistributive neut l fo + in monoidNeutralIsNeutralR (k (foldl h z fo)) + in foldExtensionality (neut <+> l) l prf export implementation Group m => Group (L a m) where @@ -372,8 +385,21 @@ implementation Monoid m => Monoid (R a m) where export implementation MonoidV m => MonoidV (R a m) where - monoidNeutralIsNeutralL = ?holeMonoidRL - monoidNeutralIsNeutralR = ?holeMonoidRR + monoidNeutralIsNeutralL r@(MkR k h z) = let + neut : R a m + neut = neutral + prf : forall t. FoldableV t => (fo : t a) -> runR (r <+> neut) fo = runR r fo + prf fo = rewrite runRSemigroupDistributive r neut fo + in monoidNeutralIsNeutralL (k (foldr h z fo)) + in foldExtensionality (r <+> neut) r prf + + monoidNeutralIsNeutralR r@(MkR k h z) = let + neut : R a m + neut = neutral + prf : forall t. FoldableV t => (fo : t a) -> runR (neut <+> r) fo = runR r fo + prf fo = rewrite runRSemigroupDistributive neut r fo + in monoidNeutralIsNeutralR (k (foldr h z fo)) + in foldExtensionality (neut <+> r) r prf export implementation Num n => Num (R a n) where From 29c0d45d4f3aa7121bcddf9990d8de8427821987 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 31 Oct 2022 13:41:41 +0100 Subject: [PATCH 113/126] Show folds form a group --- src/Data/Profunctor/Fold.idr | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/Data/Profunctor/Fold.idr b/src/Data/Profunctor/Fold.idr index 2874487..b275348 100644 --- a/src/Data/Profunctor/Fold.idr +++ b/src/Data/Profunctor/Fold.idr @@ -154,7 +154,13 @@ implementation MonoidV m => MonoidV (L a m) where export implementation Group m => Group (L a m) where inverse = map inverse - groupInverseIsInverseR = ?holeGroupL + groupInverseIsInverseR l@(MkL k h z) = let + neut : L a m + neut = neutral + prf : forall t. FoldableV t => (fo : t a) -> runL (inverse l <+> l) fo = runL neut fo + prf fo = rewrite runLSemigroupDistributive (inverse l) l fo + in groupInverseIsInverseR (k (foldl h z fo)) + in foldExtensionality (inverse l <+> l) neut prf export implementation AbelianGroup m => AbelianGroup (L a m) where @@ -419,7 +425,13 @@ implementation Abs n => Abs (R a n) where export implementation Group m => Group (R a m) where inverse = map inverse - groupInverseIsInverseR = ?holeGroupR + groupInverseIsInverseR r@(MkR k h z) = let + neut : R a m + neut = neutral + prf : forall t. FoldableV t => (fo : t a) -> runR (inverse r <+> r) fo = runR neut fo + prf fo = rewrite runRSemigroupDistributive (inverse r) r fo + in groupInverseIsInverseR (k (foldr h z fo)) + in foldExtensionality (inverse r <+> r) neut prf export implementation AbelianGroup m => AbelianGroup (R a m) where From 2f8e6119987b9e222ebe3d0adc73f7d53f381f45 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 31 Oct 2022 13:42:59 +0100 Subject: [PATCH 114/126] Show fold group ops commute --- src/Data/Profunctor/Fold.idr | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Data/Profunctor/Fold.idr b/src/Data/Profunctor/Fold.idr index b275348..fc5a027 100644 --- a/src/Data/Profunctor/Fold.idr +++ b/src/Data/Profunctor/Fold.idr @@ -164,7 +164,12 @@ implementation Group m => Group (L a m) where export implementation AbelianGroup m => AbelianGroup (L a m) where - groupOpIsCommutative = ?abelianGroupHoleL + groupOpIsCommutative l@(MkL d g u) r@(MkL f j w) = let + prf : forall t. FoldableV t => (fo : t a) -> runL (l <+> r) fo = runL (r <+> l) fo + prf fo = rewrite runLSemigroupDistributive l r fo + in rewrite groupOpIsCommutative (d (foldl g u fo)) (f (foldl j w fo)) + in sym (runLSemigroupDistributive r l fo) + in foldExtensionality (l <+> r) (r <+> l) prf export implementation Ring m => Ring (L a m) where @@ -435,7 +440,12 @@ implementation Group m => Group (R a m) where export implementation AbelianGroup m => AbelianGroup (R a m) where - groupOpIsCommutative = ?holeAbelianCommR + groupOpIsCommutative l@(MkR d g u) r@(MkR f j w) = let + prf : forall t. FoldableV t => (fo : t a) -> runR (l <+> r) fo = runR (r <+> l) fo + prf fo = rewrite runRSemigroupDistributive l r fo + in rewrite groupOpIsCommutative (d (foldr g u fo)) (f (foldr j w fo)) + in sym (runRSemigroupDistributive r l fo) + in foldExtensionality (l <+> r) (r <+> l) prf export implementation Ring m => Ring (R a m) where From d792986d75708e99630e84e3af84ca8da264525c Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 31 Oct 2022 13:44:49 +0100 Subject: [PATCH 115/126] Show distribution of run functions in rings --- src/Data/Profunctor/Fold.idr | 48 +++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/src/Data/Profunctor/Fold.idr b/src/Data/Profunctor/Fold.idr index fc5a027..dc4b0c9 100644 --- a/src/Data/Profunctor/Fold.idr +++ b/src/Data/Profunctor/Fold.idr @@ -171,12 +171,24 @@ implementation AbelianGroup m => AbelianGroup (L a m) where in sym (runLSemigroupDistributive r l fo) in foldExtensionality (l <+> r) (r <+> l) prf -export -implementation Ring m => Ring (L a m) where - (<.>) = liftA2 (<.>) - ringOpIsAssociative = ?holeRingAssocL - ringOpIsDistributiveL = ?holeRingDistrLL - ringOpIsDistributiveR = ?holeRingDistrLR +mutual + export + implementation Ring m => Ring (L a m) where + (<.>) = liftA2 (<.>) + ringOpIsAssociative = ?holeRingAssocL + ringOpIsDistributiveL = ?holeRingDistrLL + ringOpIsDistributiveR = ?holeRingDistrLR + + public export + runLRingDistributive : (FoldableV t, Ring m) => (ll, lr : L a m) -> (fo : t a) -> runL (ll <.> lr) fo = runL ll fo <.> runL lr fo + runLRingDistributive (MkL {r=r1} d g u) (MkL {r=r2} e h v) fo = let + prf : (xs : List a) -> (u : r1) -> (v : r2) -> foldl (L.step g h) (u, v) xs = (foldl g u xs, foldl h v xs) + prf [] = \_, _ => Refl + prf (x::xs) = \u, v => prf xs (g u x) (h v x) + in rewrite toListNeutralL (step g h) (u, v) fo + in rewrite toListNeutralL g u fo + in rewrite toListNeutralL h v fo + in cong (finish (\n, m => d n <.> m) e) (prf (toList fo) u v) export implementation RingWithUnity m => RingWithUnity (L a m) where @@ -447,12 +459,24 @@ implementation AbelianGroup m => AbelianGroup (R a m) where in sym (runRSemigroupDistributive r l fo) in foldExtensionality (l <+> r) (r <+> l) prf -export -implementation Ring m => Ring (R a m) where - (<.>) = liftA2 (<.>) - ringOpIsAssociative = ?holeRingAssocR - ringOpIsDistributiveL = ?holeRingDistrRL - ringOpIsDistributiveR = ?holeRingDistrRR +mutual + export + implementation Ring m => Ring (R a m) where + (<.>) = liftA2 (<.>) + ringOpIsAssociative = ?holeRingAssocR + ringOpIsDistributiveL = ?holeRingDistrRL + ringOpIsDistributiveR = ?holeRingDistrRR + + public export + runRRingDistributive : (FoldableV t, Ring m) => (rl, rr : R a m) -> (li : t a) -> runR (rl <.> rr) li = runR rl li <.> runR rr li + runRRingDistributive (MkR {r=r1} d g u) (MkR {r=r2} e h v) fo = let + prf : (xs : List a) -> foldr (R.step g h) (u, v) xs = (foldr g u xs, foldr h v xs) + prf [] = Refl + prf (x::xs) = cong (step g h x) (prf xs) + in rewrite toListNeutralR (step g h) (u, v) fo + in rewrite toListNeutralR g u fo + in rewrite toListNeutralR h v fo + in cong (Fold.finish (\n, m => d n <.> m) e) (prf (toList fo)) export implementation RingWithUnity m => RingWithUnity (R a m) where From d4a386010db1769d81a471dbedf2eb83ebbe9025 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 31 Oct 2022 13:47:35 +0100 Subject: [PATCH 116/126] Show associativity and distributivity of fold ringOps --- src/Data/Profunctor/Fold.idr | 59 ++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 6 deletions(-) diff --git a/src/Data/Profunctor/Fold.idr b/src/Data/Profunctor/Fold.idr index dc4b0c9..d7cb872 100644 --- a/src/Data/Profunctor/Fold.idr +++ b/src/Data/Profunctor/Fold.idr @@ -175,9 +175,32 @@ mutual export implementation Ring m => Ring (L a m) where (<.>) = liftA2 (<.>) - ringOpIsAssociative = ?holeRingAssocL - ringOpIsDistributiveL = ?holeRingDistrLL - ringOpIsDistributiveR = ?holeRingDistrLR + ringOpIsAssociative l@(MkL d g u) c@(MkL e h v) r@(MkL f j w) = let + prf : forall t. FoldableV t => (fo : t a) -> runL (l <.> (c <.> r)) fo = runL ((l <.> c) <.> r) fo + prf fo = rewrite runLRingDistributive l (c <.> r) fo + in rewrite runLRingDistributive c r fo + in rewrite ringOpIsAssociative (d (foldl g u fo)) (e (foldl h v fo)) (f (foldl j w fo)) + in rewrite sym (runLRingDistributive l c fo) + in sym (runLRingDistributive (l <.> c) r fo) + in foldExtensionality (l <.> (c <.> r)) ((l <.> c) <.> r) prf + ringOpIsDistributiveL l@(MkL d g u) c@(MkL e h v) r@(MkL f j w) = let + prf : forall t. FoldableV t => (fo : t a) -> runL (l <.> (c <+> r)) fo = runL ((l <.> c) <+> (l <.> r)) fo + prf fo = rewrite runLRingDistributive l (c <+> r) fo + in rewrite runLSemigroupDistributive c r fo + in rewrite ringOpIsDistributiveL (d (foldl g u fo)) (e (foldl h v fo)) (f (foldl j w fo)) + in rewrite sym (runLRingDistributive l c fo) + in rewrite sym (runLRingDistributive l r fo) + in sym (runLSemigroupDistributive (l <.> c) (l <.> r) fo) + in foldExtensionality (l <.> (c <+> r)) ((l <.> c) <+> (l <.> r)) prf + ringOpIsDistributiveR l@(MkL d g u) c@(MkL e h v) r@(MkL f j w) = let + prf : forall t. FoldableV t => (fo : t a) -> runL ((l <+> c) <.> r) fo = runL ((l <.> r) <+> (c <.> r)) fo + prf fo = rewrite runLRingDistributive (l <+> c) r fo + in rewrite runLSemigroupDistributive l c fo + in rewrite ringOpIsDistributiveR (d (foldl g u fo)) (e (foldl h v fo)) (f (foldl j w fo)) + in rewrite sym (runLRingDistributive l r fo) + in rewrite sym (runLRingDistributive c r fo) + in sym (runLSemigroupDistributive (l <.> r) (c <.> r) fo) + in foldExtensionality ((l <+> c) <.> r) ((l <.> r) <+> (c <.> r)) prf public export runLRingDistributive : (FoldableV t, Ring m) => (ll, lr : L a m) -> (fo : t a) -> runL (ll <.> lr) fo = runL ll fo <.> runL lr fo @@ -463,9 +486,33 @@ mutual export implementation Ring m => Ring (R a m) where (<.>) = liftA2 (<.>) - ringOpIsAssociative = ?holeRingAssocR - ringOpIsDistributiveL = ?holeRingDistrRL - ringOpIsDistributiveR = ?holeRingDistrRR + ringOpIsAssociative l@(MkR d g u) c@(MkR e h v) r@(MkR f j w) = let + prf : forall t. FoldableV t => (fo : t a) -> runR (l <.> (c <.> r)) fo = runR ((l <.> c) <.> r) fo + prf fo = rewrite runRRingDistributive l (c <.> r) fo + in rewrite runRRingDistributive c r fo + in rewrite ringOpIsAssociative (d (foldr g u fo)) (e (foldr h v fo)) (f (foldr j w fo)) + in rewrite sym (runRRingDistributive l c fo) + in sym (runRRingDistributive (l <.> c) r fo) + in foldExtensionality (l <.> (c <.> r)) ((l <.> c) <.> r) prf + ringOpIsDistributiveL l@(MkR d g u) c@(MkR e h v) r@(MkR f j w) = let + prf : forall t. FoldableV t => (fo : t a) -> runR (l <.> (c <+> r)) fo = runR ((l <.> c) <+> (l <.> r)) fo + prf fo = rewrite runRRingDistributive l (c <+> r) fo + in rewrite runRSemigroupDistributive c r fo + in rewrite ringOpIsDistributiveL (d (foldr g u fo)) (e (foldr h v fo)) (f (foldr j w fo)) + in rewrite sym (runRRingDistributive l c fo) + in rewrite sym (runRRingDistributive l r fo) + in sym (runRSemigroupDistributive (l <.> c) (l <.> r) fo) + in foldExtensionality (l <.> (c <+> r)) ((l <.> c) <+> (l <.> r)) prf + + ringOpIsDistributiveR l@(MkR d g u) c@(MkR e h v) r@(MkR f j w) = let + prf : forall t. FoldableV t => (fo : t a) -> runR ((l <+> c) <.> r) fo = runR ((l <.> r) <+> (c <.> r)) fo + prf fo = rewrite runRRingDistributive (l <+> c) r fo + in rewrite runRSemigroupDistributive l c fo + in rewrite ringOpIsDistributiveR (d (foldr g u fo)) (e (foldr h v fo)) (f (foldr j w fo)) + in rewrite sym (runRRingDistributive l r fo) + in rewrite sym (runRRingDistributive c r fo) + in sym (runRSemigroupDistributive (l <.> r) (c <.> r) fo) + in foldExtensionality ((l <+> c) <.> r) ((l <.> r) <+> (c <.> r)) prf public export runRRingDistributive : (FoldableV t, Ring m) => (rl, rr : R a m) -> (li : t a) -> runR (rl <.> rr) li = runR rl li <.> runR rr li From b9211426eb83455903c66ed0a6890e06fb078af3 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 31 Oct 2022 13:48:11 +0100 Subject: [PATCH 117/126] Show fold ring unity is identity --- src/Data/Profunctor/Fold.idr | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/Data/Profunctor/Fold.idr b/src/Data/Profunctor/Fold.idr index d7cb872..2c71123 100644 --- a/src/Data/Profunctor/Fold.idr +++ b/src/Data/Profunctor/Fold.idr @@ -216,8 +216,20 @@ mutual export implementation RingWithUnity m => RingWithUnity (L a m) where unity = pure unity - unityIsRingIdL = ?holeRingUnityLL - unityIsRingIdR = ?holeRingUnityLR + unityIsRingIdL l@(MkL d g u) = let + uni : L a m + uni = unity + prf : forall t. FoldableV t => (fo : t a) -> runL (l <.> uni) fo = runL l fo + prf fo = rewrite runLRingDistributive l uni fo + in unityIsRingIdL (d (foldl g u fo)) + in foldExtensionality (l <.> uni) l prf + unityIsRingIdR l@(MkL d g u) = let + uni : L a m + uni = unity + prf : forall t. FoldableV t => (fo : t a) -> runL (uni <.> l) fo = runL l fo + prf fo = rewrite runLRingDistributive uni l fo + in unityIsRingIdR (d (foldl g u fo)) + in foldExtensionality (uni <.> l) l prf -- The `Field` implementation won't type check, but it should exist @@ -528,8 +540,20 @@ mutual export implementation RingWithUnity m => RingWithUnity (R a m) where unity = pure unity - unityIsRingIdL = ?holeRingUnityRL - unityIsRingIdR = ?holeRingUnityRR + unityIsRingIdL r@(MkR d g u) = let + uni : R a m + uni = unity + prf : forall t. FoldableV t => (fo : t a) -> runR (r <.> uni) fo = runR r fo + prf fo = rewrite runRRingDistributive r uni fo + in unityIsRingIdL (d (foldr g u fo)) + in foldExtensionality (r <.> uni) r prf + unityIsRingIdR r@(MkR d g u) = let + uni : R a m + uni = unity + prf : forall t. FoldableV t => (fo : t a) -> runR (uni <.> r) fo = runR r fo + prf fo = rewrite runRRingDistributive uni r fo + in unityIsRingIdR (d (foldr g u fo)) + in foldExtensionality (uni <.> r) r prf ||| Convert an `L` to an `R` export From e6925ff3009ac9cdaa43007e0c0875e708b35121 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 31 Oct 2022 14:33:38 +0100 Subject: [PATCH 118/126] Add FoldableV instances for prelude foldables --- src/Data/Verified/Foldable.idr | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/Data/Verified/Foldable.idr b/src/Data/Verified/Foldable.idr index a89c284..0c0e20a 100644 --- a/src/Data/Verified/Foldable.idr +++ b/src/Data/Verified/Foldable.idr @@ -7,3 +7,22 @@ interface Foldable t => FoldableV t where toListNeutralL : (f : r -> a -> r) -> (z : r) -> (fo : t a) -> foldl f z fo = foldl f z (Prelude.toList fo) toListNeutralR : (f : a -> r -> r) -> (z : r) -> (fo : t a) -> foldr f z fo = foldr f z (Prelude.toList fo) +export +implementation FoldableV Maybe where + toListNeutralL f z Nothing = Refl + toListNeutralL f z (Just x) = Refl + toListNeutralR f z Nothing = Refl + toListNeutralR f z (Just x) = Refl + +export +implementation FoldableV (Either e) where + toListNeutralL f z (Left x) = Refl + toListNeutralL f z (Right x) = Refl + toListNeutralR f z (Left x) = Refl + toListNeutralR f z (Right x) = Refl + +export +implementation FoldableV List where + toListNeutralL f z fo = Refl + toListNeutralR f z fo = Refl + From c5960d4f2cf8c9da30d8518accbc54fbd0676c99 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 31 Oct 2022 14:39:44 +0100 Subject: [PATCH 119/126] Add other trivial FoldableV instances --- src/Data/Verified/Foldable.idr | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/Data/Verified/Foldable.idr b/src/Data/Verified/Foldable.idr index 0c0e20a..d82baa5 100644 --- a/src/Data/Verified/Foldable.idr +++ b/src/Data/Verified/Foldable.idr @@ -1,5 +1,10 @@ module Data.Verified.Foldable +import Control.Applicative.Const +import Data.List1 +import Data.Validated +import Text.Bounded + %default total public export @@ -26,3 +31,24 @@ implementation FoldableV List where toListNeutralL f z fo = Refl toListNeutralR f z fo = Refl +export +implementation FoldableV (Const a) where + toListNeutralL f z xs = Refl + toListNeutralR f z xs = Refl + +export +implementation FoldableV List1 where + toListNeutralL f z (x ::: xs) = Refl + toListNeutralR f z (x ::: xs) = Refl + +export +implementation FoldableV (Validated e) where + toListNeutralL f z (Valid x) = Refl + toListNeutralL f z (Invalid _) = Refl + toListNeutralR f z (Valid x) = Refl + toListNeutralR f z (Invalid _) = Refl + +export +implementation FoldableV WithBounds where + toListNeutralL f z xs = Refl + toListNeutralR f z xs = Refl From 2307812e11b2242c871fafb29f1de4f8cf9c69e5 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 31 Oct 2022 15:10:06 +0100 Subject: [PATCH 120/126] Verify toList neutrality for vectors --- src/Data/Verified/Foldable.idr | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/Data/Verified/Foldable.idr b/src/Data/Verified/Foldable.idr index d82baa5..668f319 100644 --- a/src/Data/Verified/Foldable.idr +++ b/src/Data/Verified/Foldable.idr @@ -3,6 +3,8 @@ module Data.Verified.Foldable import Control.Applicative.Const import Data.List1 import Data.Validated +import Data.Vect +import Data.Vect.Properties.Foldr import Text.Bounded %default total @@ -52,3 +54,21 @@ export implementation FoldableV WithBounds where toListNeutralL f z xs = Refl toListNeutralR f z xs = Refl + +export +implementation FoldableV (Vect n) where + toListNeutralL f z xs = let + foldlEmptyIndependent : (f : r -> a -> r) -> (xs : Vect m a) -> (z : r) -> foldl f z xs = foldl f z (toList xs) + foldlEmptyIndependent f Nil = \_ => Refl + foldlEmptyIndependent f (y :: ys) = let homomorphism = foldrVectHomomorphism.cons {A=a, F=(::), E=[]} + in \z => rewrite foldlEmptyIndependent f ys (f z y) + in cong (foldl f z) (sym (homomorphism y ys)) + in foldlEmptyIndependent f xs z + toListNeutralR f z Nil = Refl + toListNeutralR f z (x :: xs) = let + vectHomomorphismCons = foldrVectHomomorphism.cons {A=a, F=(::), E=[]} + vectHomomorphismF = foldrVectHomomorphism.cons {A=a, F=f, E=z} + in rewrite vectHomomorphismCons x xs + in rewrite sym (toListNeutralR f z xs) + in vectHomomorphismF x xs + From 64104c575ee17b27b29db76e7575b00eb9b7d52f Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 31 Oct 2022 15:11:16 +0100 Subject: [PATCH 121/126] Verify toList neutrality for sorted sets --- src/Data/Verified/Foldable.idr | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/Data/Verified/Foldable.idr b/src/Data/Verified/Foldable.idr index 668f319..7fb5482 100644 --- a/src/Data/Verified/Foldable.idr +++ b/src/Data/Verified/Foldable.idr @@ -2,6 +2,7 @@ module Data.Verified.Foldable import Control.Applicative.Const import Data.List1 +import Data.SortedSet import Data.Validated import Data.Vect import Data.Vect.Properties.Foldr @@ -72,3 +73,13 @@ implementation FoldableV (Vect n) where in rewrite sym (toListNeutralR f z xs) in vectHomomorphismF x xs +namespace SortedSet + toListRedundant : (xs : List a) -> xs = foldr (::) [] xs + toListRedundant [] = Refl + toListRedundant (x::xs) = cong (x::) (toListRedundant xs) + + export + implementation FoldableV SortedSet where + toListNeutralL f z xs = cong (foldl {t=List} f z) (toListRedundant (SortedSet.toList xs)) + toListNeutralR f z xs = cong (foldr {t=List} f z) (toListRedundant (SortedSet.toList xs)) + From 3ca5a45204b9aaf8c42df151dfc74a0795c299fa Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 31 Oct 2022 15:11:35 +0100 Subject: [PATCH 122/126] Verify toList neutrality for LazyLists and SnocLists --- src/Data/Verified/Foldable.idr | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/Data/Verified/Foldable.idr b/src/Data/Verified/Foldable.idr index 7fb5482..cce916d 100644 --- a/src/Data/Verified/Foldable.idr +++ b/src/Data/Verified/Foldable.idr @@ -1,7 +1,9 @@ module Data.Verified.Foldable import Control.Applicative.Const +import Data.List.Lazy import Data.List1 +import Data.SnocList import Data.SortedSet import Data.Validated import Data.Vect @@ -83,3 +85,30 @@ namespace SortedSet toListNeutralL f z xs = cong (foldl {t=List} f z) (toListRedundant (SortedSet.toList xs)) toListNeutralR f z xs = cong (foldr {t=List} f z) (toListRedundant (SortedSet.toList xs)) +export +implementation FoldableV SnocList where + toListNeutralL f z sn = snocFoldlAsListFoldl f z sn + toListNeutralR f z sn = let + foldrListAppendDistributive : (f : a -> r -> r) -> (z : r) -> (l1, l2 : List a) + -> foldr f (foldr f z l2) l1 = foldr f z (l1 ++ l2) + foldrListAppendDistributive f z [] = \_ => Refl + foldrListAppendDistributive f z (x::xs) = \li => cong (f x) (foldrListAppendDistributive f z xs li) + + snocFoldrAsListFoldr : (f : a -> r -> r) -> (xs : SnocList a) -> (init : r) -> foldr f init xs = foldr f init (toList xs) + snocFoldrAsListFoldr f Lin = \_ => Refl + snocFoldrAsListFoldr f (xs :< x) = \init => + rewrite snocFoldrAsListFoldr f xs (f x init) + in rewrite chipsAsListAppend xs [x] + in foldrListAppendDistributive f init (xs <>> []) [x] + in snocFoldrAsListFoldr f sn z + +export +implementation FoldableV LazyList where + toListNeutralL f z xs = let + foldlEmptyIndependent : (f : r -> a -> r) -> (xs : LazyList a) -> (z : r) -> foldl f z xs = foldl f z (toList xs) + foldlEmptyIndependent f [] = \_ => Refl + foldlEmptyIndependent f (y::ys) = \z => foldlEmptyIndependent f ys (f z y) + in foldlEmptyIndependent f xs z + toListNeutralR f z [] = Refl + toListNeutralR f z (x::xs) = cong (f x) (toListNeutralR f z xs) + From d57107b0903471f02d8751dd33ae1290f7cacb21 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 31 Oct 2022 15:16:27 +0100 Subject: [PATCH 123/126] Verify toList neutrality for sorted maps --- src/Data/Verified/Foldable.idr | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Data/Verified/Foldable.idr b/src/Data/Verified/Foldable.idr index cce916d..e9868b8 100644 --- a/src/Data/Verified/Foldable.idr +++ b/src/Data/Verified/Foldable.idr @@ -5,6 +5,7 @@ import Data.List.Lazy import Data.List1 import Data.SnocList import Data.SortedSet +import Data.SortedMap import Data.Validated import Data.Vect import Data.Vect.Properties.Foldr @@ -85,6 +86,11 @@ namespace SortedSet toListNeutralL f z xs = cong (foldl {t=List} f z) (toListRedundant (SortedSet.toList xs)) toListNeutralR f z xs = cong (foldr {t=List} f z) (toListRedundant (SortedSet.toList xs)) + export + implementation FoldableV (SortedMap k) where + toListNeutralL f z xs = cong (foldl {t=List} f z) (toListRedundant (values xs)) + toListNeutralR f z xs = cong (foldr {t=List} f z) (toListRedundant (values xs)) + export implementation FoldableV SnocList where toListNeutralL f z sn = snocFoldlAsListFoldl f z sn From b1bd25bb2f811ff69a4c75cedc1dff080a4e0930 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Mon, 31 Oct 2022 15:32:28 +0100 Subject: [PATCH 124/126] Verify toList neutrality for alternating lists --- src/Data/Verified/Foldable.idr | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/Data/Verified/Foldable.idr b/src/Data/Verified/Foldable.idr index e9868b8..289814b 100644 --- a/src/Data/Verified/Foldable.idr +++ b/src/Data/Verified/Foldable.idr @@ -1,6 +1,7 @@ module Data.Verified.Foldable import Control.Applicative.Const +import Data.List.Alternating import Data.List.Lazy import Data.List1 import Data.SnocList @@ -118,3 +119,21 @@ implementation FoldableV LazyList where toListNeutralR f z [] = Refl toListNeutralR f z (x::xs) = cong (f x) (toListNeutralR f z xs) +export +implementation FoldableV (Odd b) where + toListNeutralL f z odd = let + foldlEmptyIndependent : (f : r -> a -> r) -> (xs : Odd b a) -> (z : r) -> foldl f z xs = foldl f z (toList xs) + foldlEmptyIndependent f (x :: xs) with (xs) + _ | Nil = \_ => Refl + _ | (y :: ys) with (ys) + _ | (n :: ns) with (ns) + _ | Nil = \_ => Refl + _ | (m :: ms) = \z => foldlEmptyIndependent f ms (f (f z y) m) + in foldlEmptyIndependent f odd z + toListNeutralR f z (x :: xs) with (xs) + _ | Nil = Refl + _ | (y :: ys) with (ys) + _ | (n :: ns) with (ns) + _ | Nil = Refl + _ | (m :: ms) = let rec = toListNeutralR f z ms in cong (f y) (cong (f m) (toListNeutralR f z ms)) + From 35758b9ce1537006a5eb19b494721a9baae18529 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Wed, 2 Nov 2022 10:43:17 +0100 Subject: [PATCH 125/126] Verify toList neutrality for MaybeT --- src/Data/Verified/Foldable.idr | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/Data/Verified/Foldable.idr b/src/Data/Verified/Foldable.idr index 289814b..47b160d 100644 --- a/src/Data/Verified/Foldable.idr +++ b/src/Data/Verified/Foldable.idr @@ -1,6 +1,7 @@ module Data.Verified.Foldable import Control.Applicative.Const +import Control.Monad.Maybe import Data.List.Alternating import Data.List.Lazy import Data.List1 @@ -27,6 +28,33 @@ implementation FoldableV Maybe where toListNeutralR f z (Just x) = Refl export +implementation FoldableV m => FoldableV (MaybeT m) where + toListNeutralL f z m@(MkMaybeT mm) = let + funEq : (x : c) -> (g : c -> d) -> (f : c -> d) -> g = f -> g x = f x + funEq x g f hyp = rewrite hyp in Refl + in rewrite funEq + z + ( foldr (\x, xs => maybe (Delay xs) (Delay (\arg, x => xs (f x arg))) x) id mm ) + ( foldr (\x, xs => maybe (Delay xs) (Delay (\arg, x => xs (f x arg))) x) id (toList mm)) + $ toListNeutralR (\x, xs => maybe (Delay xs) (Delay (\arg, x => xs (f x arg))) x) id mm + in rewrite toListNeutralR (\x, xs => maybe (Delay xs) (Delay (\arg => arg :: xs)) x) Prelude.Nil mm + in prf (toList mm) z + where prf : (l : List (Maybe a)) -> (zz : r) + -> foldr (\x, xs => maybe (Delay xs) (Delay (\arg, x => xs (f x arg))) x) Prelude.Basics.id l zz + = foldl f zz (foldr (\x,xs => maybe (Delay xs) (Delay (\arg => arg :: xs)) x) Prelude.Nil l) + prf [] = \_ => Refl + prf (Nothing::xs) = \zz => prf xs zz + prf (Just x ::xs) = \zz => prf xs (f zz x) + toListNeutralR f z (MkMaybeT mm) = rewrite toListNeutralR (\x, xs => maybe (Delay xs) (Delay (\arg => f arg xs)) x) z mm + in rewrite toListNeutralR (\x, xs => maybe (Delay xs) (Delay (\arg => arg :: xs)) x) Prelude.Nil mm + in prf (toList mm) + where prf : (l : List (Maybe a)) + -> foldr (\x, xs => maybe (Delay xs) (Delay (\arg => f arg xs)) x) z l + = foldr f z (foldr (\x,xs => maybe (Delay xs) (Delay (\arg => arg :: xs)) x) Prelude.Nil l) + prf [] = Refl + prf (Nothing::xs) = prf xs + prf ((Just x)::xs) = cong (f x) (prf xs) +export implementation FoldableV (Either e) where toListNeutralL f z (Left x) = Refl toListNeutralL f z (Right x) = Refl From b37040138c8303539e77181aff467100c402d8a2 Mon Sep 17 00:00:00 2001 From: Simon Plakolb Date: Wed, 2 Nov 2022 10:50:31 +0100 Subject: [PATCH 126/126] Verify toList neutrality for EitherT --- src/Data/Verified/Foldable.idr | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/Data/Verified/Foldable.idr b/src/Data/Verified/Foldable.idr index 47b160d..8987cfc 100644 --- a/src/Data/Verified/Foldable.idr +++ b/src/Data/Verified/Foldable.idr @@ -1,6 +1,7 @@ module Data.Verified.Foldable import Control.Applicative.Const +import Control.Monad.Either import Control.Monad.Maybe import Data.List.Alternating import Data.List.Lazy @@ -53,7 +54,7 @@ implementation FoldableV m => FoldableV (MaybeT m) where = foldr f z (foldr (\x,xs => maybe (Delay xs) (Delay (\arg => arg :: xs)) x) Prelude.Nil l) prf [] = Refl prf (Nothing::xs) = prf xs - prf ((Just x)::xs) = cong (f x) (prf xs) + prf (Just x ::xs) = cong (f x) (prf xs) export implementation FoldableV (Either e) where toListNeutralL f z (Left x) = Refl @@ -61,6 +62,34 @@ implementation FoldableV (Either e) where toListNeutralR f z (Left x) = Refl toListNeutralR f z (Right x) = Refl +export +implementation FoldableV m => FoldableV (EitherT e m) where + toListNeutralL f z m@(MkEitherT mm) = let + funEq : (x : c) -> (g : c -> d) -> (f : c -> d) -> g = f -> g x = f x + funEq x g f hyp = rewrite hyp in Refl + in rewrite funEq + z + ( foldr (\x, xs => either (Delay (const xs)) (Delay (\arg, x => xs (f x arg))) x) id mm ) + ( foldr (\x, xs => either (Delay (const xs)) (Delay (\arg, x => xs (f x arg))) x) id (toList mm)) + $ toListNeutralR (\x, xs => either (Delay (const xs)) (Delay (\arg, x => xs (f x arg))) x) id mm + in rewrite toListNeutralR (\x, xs => either (Delay (const xs)) (Delay (\arg => arg :: xs)) x) Prelude.Nil mm + in prf (toList mm) z + where prf : (l : List (Either e a)) -> (zz : r) + -> foldr (\x, xs => either (Delay (const xs)) (Delay (\arg, x => xs (f x arg))) x) Prelude.Basics.id l zz + = foldl f zz (foldr (\x,xs => either (Delay (const xs)) (Delay (\arg => arg :: xs)) x) Prelude.Nil l) + prf [] = \_ => Refl + prf (Left e ::xs) = \zz => prf xs zz + prf (Right x::xs) = \zz => prf xs (f zz x) + toListNeutralR f z m@(MkEitherT mm) = rewrite toListNeutralR (\x, xs => either (Delay (const xs)) (Delay (\arg => f arg xs)) x) z mm + in rewrite toListNeutralR (\x, xs => either (Delay (const xs)) (Delay (\arg => arg :: xs)) x) Prelude.Nil mm + in prf (toList mm) + where prf : (l : List (Either e a)) + -> foldr (\x, xs => either (Delay (const xs)) (Delay (\arg => f arg xs)) x) z l + = foldr f z (foldr (\x, xs => either (Delay (const xs)) (Delay (\arg => arg :: xs)) x) Prelude.Nil l) + prf [] = Refl + prf (Left e ::xs) = prf xs + prf (Right x::xs) = cong (f x) (prf xs) + export implementation FoldableV List where toListNeutralL f z fo = Refl