From 24d71e1f88c879173156fd21d6209b06c61e92a0 Mon Sep 17 00:00:00 2001 From: FintanH Date: Sat, 2 Feb 2019 10:48:13 +0000 Subject: [PATCH 01/25] Clean up Monad Type --- Monad/Type | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/Monad/Type b/Monad/Type index ba9380d..841f986 100644 --- a/Monad/Type +++ b/Monad/Type @@ -1,10 +1,7 @@ let Applicative = ./../Applicative/Type -in let Monad - : (Type → Type) → Type - = λ(f : Type → Type) - → { bind : - ∀(a : Type) → ∀(b : Type) → ∀(fa : f a) → ∀(k : a → f b) → f b - } - -in λ(f : Type → Type) → Applicative f ⩓ Monad f +in λ(f : Type → Type) + → Applicative f + ⩓ { bind : + ∀(a : Type) → ∀(b : Type) → ∀(fa : f a) → ∀(k : a → f b) → f b + } From c21b64482e08fc3de8464df657cc38b0dae0ad5d Mon Sep 17 00:00:00 2001 From: FintanH Date: Sat, 2 Feb 2019 11:36:54 +0000 Subject: [PATCH 02/25] Add flipEither and hush --- Either/flipEither | 7 +++++++ Either/hush | 5 +++++ 2 files changed, 12 insertions(+) create mode 100644 Either/flipEither create mode 100644 Either/hush diff --git a/Either/flipEither b/Either/flipEither new file mode 100644 index 0000000..2ec6c3a --- /dev/null +++ b/Either/flipEither @@ -0,0 +1,7 @@ + let Either = ./Type + +in λ(a : Type) + → λ(b : Type) + → let E = constructors (Either b a) + + in ./fold a b (Either b a) E.Right E.Left diff --git a/Either/hush b/Either/hush new file mode 100644 index 0000000..84f81c8 --- /dev/null +++ b/Either/hush @@ -0,0 +1,5 @@ + let Either = ./Type + +in λ(a : Type) + → λ(b : Type) + → ./fold a b (Optional b) (λ(_ : a) → None) (λ(x : b) → Some x) From 8460fbb54a2d3fdb5b501406de9b569ce106c0a1 Mon Sep 17 00:00:00 2001 From: FintanH Date: Sat, 2 Feb 2019 12:11:04 +0000 Subject: [PATCH 03/25] Use [] annotation for None --- Either/hush | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Either/hush b/Either/hush index 84f81c8..efc208e 100644 --- a/Either/hush +++ b/Either/hush @@ -2,4 +2,4 @@ in λ(a : Type) → λ(b : Type) - → ./fold a b (Optional b) (λ(_ : a) → None) (λ(x : b) → Some x) + → ./fold a b (Optional b) (λ(_ : a) → [] : Optional b) (λ(x : b) → Some x) From 333e45448bb5b943389d88fc3523fd2a40ad34b0 Mon Sep 17 00:00:00 2001 From: FintanH Date: Sat, 2 Feb 2019 12:11:25 +0000 Subject: [PATCH 04/25] Add base type class for Compactable and from functions --- Compactable/Type | 14 ++++++++++++++ Compactable/fromCompact | 31 +++++++++++++++++++++++++++++++ Compactable/fromSeparate | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+) create mode 100644 Compactable/Type create mode 100644 Compactable/fromCompact create mode 100644 Compactable/fromSeparate diff --git a/Compactable/Type b/Compactable/Type new file mode 100644 index 0000000..86ac283 --- /dev/null +++ b/Compactable/Type @@ -0,0 +1,14 @@ + let Either = ./../Either/Type + +in let Functor = ./../Functor/Type + +in λ(f : Type → Type) + → { compact : + ∀(functor : Functor f) → ∀(a : Type) → f (Optional a) → f a + , separate : + ∀(functor : Functor f) + → ∀(a : Type) + → ∀(b : Type) + → f (Either a b) + → { _1 : f a, _2 : f b } + } diff --git a/Compactable/fromCompact b/Compactable/fromCompact new file mode 100644 index 0000000..686bf51 --- /dev/null +++ b/Compactable/fromCompact @@ -0,0 +1,31 @@ + let Either = ./../Either/Type + +in let Functor = ./../Functor/Type + +in let flipEither = ../Either/flipEither + +in let hush = ../Either/hush + +in λ(f : Type → Type) + → λ(compact : ∀(functor : Functor f) → ∀(a : Type) → f (Optional a) → f a) + → { compact = + compact + , separate = + λ(functor : Functor f) + → λ(a : Type) + → λ(b : Type) + → λ(eithers : f (Either a b)) + → { _1 = + compact + functor + a + ( functor.map + (Either a b) + (Optional a) + (λ(either : Either a b) → hush b a (flipEither a b either)) + eithers + ) + , _2 = + compact functor b (functor.map (Either a b) (Optional b) (hush a b) eithers) + } + } diff --git a/Compactable/fromSeparate b/Compactable/fromSeparate new file mode 100644 index 0000000..5a5b3b4 --- /dev/null +++ b/Compactable/fromSeparate @@ -0,0 +1,39 @@ + let Either = ./../Either/Type + +in let Functor = ./../Functor/Type + +in λ(f : Type → Type) + → λ ( separate + : ∀(functor : Functor f) + → ∀(a : Type) + → ∀(b : Type) + → f (Either a b) + → { _1 : f a, _2 : f b } + ) + → { separate = + separate + , compact = + λ(functor : Functor f) + → λ(a : Type) + → λ(optionals : f (Optional a)) + → let E = constructors (Either a {}) + + in ( separate + functor + a + {} + ( functor.map + (Optional a) + (Either a {}) + ( λ(optional : Optional a) + → Optional/fold + a + optional + (Either a {}) + E.Left + (E.Right {=}) + ) + optionals + ) + )._1 + } From 74b40fa17f9a9a91f53ac83abe5dac805653a331 Mon Sep 17 00:00:00 2001 From: FintanH Date: Sat, 2 Feb 2019 13:39:37 +0000 Subject: [PATCH 05/25] Use None instead of [] --- Either/hush | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Either/hush b/Either/hush index efc208e..0879676 100644 --- a/Either/hush +++ b/Either/hush @@ -2,4 +2,4 @@ in λ(a : Type) → λ(b : Type) - → ./fold a b (Optional b) (λ(_ : a) → [] : Optional b) (λ(x : b) → Some x) + → ./fold a b (Optional b) (λ(_ : a) → None b) (λ(x : b) → Some x) From c0eaf24c64bac7c2a10ed0ed5b43259efc6e64b6 Mon Sep 17 00:00:00 2001 From: FintanH Date: Sat, 2 Feb 2019 14:08:59 +0000 Subject: [PATCH 06/25] Run linter --- Compactable/fromCompact | 9 ++++++--- Either/hush | 8 +++----- Optional/applicative | 4 ++-- Optional/functor | 7 +------ Optional/monad | 2 +- Optional/traversable | 8 ++------ 6 files changed, 15 insertions(+), 23 deletions(-) diff --git a/Compactable/fromCompact b/Compactable/fromCompact index 686bf51..ef69cf6 100644 --- a/Compactable/fromCompact +++ b/Compactable/fromCompact @@ -2,9 +2,9 @@ in let Functor = ./../Functor/Type -in let flipEither = ../Either/flipEither +in let flipEither = ./../Either/flipEither -in let hush = ../Either/hush +in let hush = ./../Either/hush in λ(f : Type → Type) → λ(compact : ∀(functor : Functor f) → ∀(a : Type) → f (Optional a) → f a) @@ -26,6 +26,9 @@ in λ(f : Type → Type) eithers ) , _2 = - compact functor b (functor.map (Either a b) (Optional b) (hush a b) eithers) + compact + functor + b + (functor.map (Either a b) (Optional b) (hush a b) eithers) } } diff --git a/Either/hush b/Either/hush index 0879676..e9b3efe 100644 --- a/Either/hush +++ b/Either/hush @@ -1,5 +1,3 @@ - let Either = ./Type - -in λ(a : Type) - → λ(b : Type) - → ./fold a b (Optional b) (λ(_ : a) → None b) (λ(x : b) → Some x) + λ(a : Type) +→ λ(b : Type) +→ ./fold a b (Optional b) (λ(_ : a) → None b) (λ(x : b) → Some x) diff --git a/Optional/applicative b/Optional/applicative index 1238d92..a23ad94 100644 --- a/Optional/applicative +++ b/Optional/applicative @@ -7,7 +7,7 @@ in let map = (./functor).map in ./functor ∧ { pure = - λ(a : Type) → λ(x : a) → [ x ] : Optional a + λ(a : Type) → λ(x : a) → Some x , ap = λ(a : Type) → λ(b : Type) @@ -18,6 +18,6 @@ in ./functor g (Optional b) (λ(k : a → b) → λ(o : Optional b) → map a b k fa) - ([] : Optional b) + (None b) } : Applicative Optional diff --git a/Optional/functor b/Optional/functor index 1fea515..995db2b 100644 --- a/Optional/functor +++ b/Optional/functor @@ -3,11 +3,6 @@ → λ(b : Type) → λ(f : a → b) → λ(o : Optional a) - → Optional/fold - a - o - (Optional b) - (λ(x : a) → [ f x ] : Optional b) - ([] : Optional b) + → Optional/fold a o (Optional b) (λ(x : a) → Some (f x)) (None b) } : ./../Functor/Type Optional diff --git a/Optional/monad b/Optional/monad index 5974d2e..db94244 100644 --- a/Optional/monad +++ b/Optional/monad @@ -10,7 +10,7 @@ in let concat = x (Optional a) (λ(y : Optional a) → y) - ([] : Optional a) + (None a) in ./applicative ∧ { bind = diff --git a/Optional/traversable b/Optional/traversable index 33dcf13..438f5ad 100644 --- a/Optional/traversable +++ b/Optional/traversable @@ -16,12 +16,8 @@ in ./foldable ts (f (Optional b)) ( λ(x : a) - → applicative.map - b - (Optional b) - (λ(y : b) → [ y ] : Optional b) - (g x) + → applicative.map b (Optional b) (λ(y : b) → Some y) (g x) ) - (applicative.pure (Optional b) ([] : Optional b)) + (applicative.pure (Optional b) (None b)) } : Traversable Optional From bb8dbd549b7667bb3daa04d3690d3881255b0f84 Mon Sep 17 00:00:00 2001 From: FintanH Date: Sat, 2 Feb 2019 14:09:19 +0000 Subject: [PATCH 07/25] Add Compactable combinators --- Compactable/apEither | 18 ++++++++++++++++++ Compactable/apMaybe | 15 +++++++++++++++ Compactable/bindEither | 14 ++++++++++++++ Compactable/bindMaybe | 12 ++++++++++++ Compactable/mapEither | 12 ++++++++++++ Compactable/mapMaybe | 10 ++++++++++ Compactable/traverseEither | 22 ++++++++++++++++++++++ Compactable/traverseMaybe | 20 ++++++++++++++++++++ 8 files changed, 123 insertions(+) create mode 100644 Compactable/apEither create mode 100644 Compactable/apMaybe create mode 100644 Compactable/bindEither create mode 100644 Compactable/bindMaybe create mode 100644 Compactable/mapEither create mode 100644 Compactable/mapMaybe create mode 100644 Compactable/traverseEither create mode 100644 Compactable/traverseMaybe diff --git a/Compactable/apEither b/Compactable/apEither new file mode 100644 index 0000000..3b08e9e --- /dev/null +++ b/Compactable/apEither @@ -0,0 +1,18 @@ + let Applicative = ./../Applicative/Type + +in let extractFunctor = ./../Applicative/extractFunctor + +in let Either = ./../Either/Type + +in λ(f : Type → Type) + → λ(c : ./Type f) + → λ(applicative : Applicative f) + → λ(a : Type) + → λ(b : Type) + → λ(k : f (a → Either a b)) + → λ(fa : f a) + → c.separate + (extractFunctor f applicative) + a + b + (applicative.ap a (Either a b) k fa) diff --git a/Compactable/apMaybe b/Compactable/apMaybe new file mode 100644 index 0000000..664ccc1 --- /dev/null +++ b/Compactable/apMaybe @@ -0,0 +1,15 @@ + let Applicative = ./../Applicative/Type + +in let extractFunctor = ./../Applicative/extractFunctor + +in λ(f : Type → Type) + → λ(c : ./Type f) + → λ(applicative : Applicative f) + → λ(a : Type) + → λ(b : Type) + → λ(k : f (a → Optional b)) + → λ(fa : f a) + → c.compact + (extractFunctor f applicative) + b + (applicative.ap a (Optional b) k fa) diff --git a/Compactable/bindEither b/Compactable/bindEither new file mode 100644 index 0000000..2c74a44 --- /dev/null +++ b/Compactable/bindEither @@ -0,0 +1,14 @@ + let Monad = ./../Monad/Type + +in let extractFunctor = ./../Monad/extractFunctor + +in let Either = ./../Either/Type + +in λ(f : Type → Type) + → λ(c : ./Type f) + → λ(monad : Monad f) + → λ(a : Type) + → λ(b : Type) + → λ(k : a → f (Either a b)) + → λ(fa : f a) + → c.separate (extractFunctor f monad) a b (monad.bind a (Either a b) fa k) diff --git a/Compactable/bindMaybe b/Compactable/bindMaybe new file mode 100644 index 0000000..1c97216 --- /dev/null +++ b/Compactable/bindMaybe @@ -0,0 +1,12 @@ + let Monad = ./../Monad/Type + +in let extractFunctor = ./../Monad/extractFunctor + +in λ(f : Type → Type) + → λ(c : ./Type f) + → λ(monad : Monad f) + → λ(a : Type) + → λ(b : Type) + → λ(k : a → f (Optional b)) + → λ(fa : f a) + → c.compact (extractFunctor f monad) b (monad.bind a (Optional b) fa k) diff --git a/Compactable/mapEither b/Compactable/mapEither new file mode 100644 index 0000000..4218314 --- /dev/null +++ b/Compactable/mapEither @@ -0,0 +1,12 @@ + let Functor = ./../Functor/Type + +in let Either = ./../Either/Type + +in λ(f : Type → Type) + → λ(c : ./Type f) + → λ(functor : Functor f) + → λ(a : Type) + → λ(b : Type) + → λ(k : a → Either a b) + → λ(fa : f a) + → c.separate functor a b (functor.map a (Either a b) k fa) diff --git a/Compactable/mapMaybe b/Compactable/mapMaybe new file mode 100644 index 0000000..0a78f9e --- /dev/null +++ b/Compactable/mapMaybe @@ -0,0 +1,10 @@ + let Functor = ./../Functor/Type + +in λ(f : Type → Type) + → λ(c : ./Type f) + → λ(functor : Functor f) + → λ(a : Type) + → λ(b : Type) + → λ(k : a → Optional b) + → λ(fa : f a) + → c.compact functor b (functor.map a (Optional b) k fa) diff --git a/Compactable/traverseEither b/Compactable/traverseEither new file mode 100644 index 0000000..84cf736 --- /dev/null +++ b/Compactable/traverseEither @@ -0,0 +1,22 @@ + let Traversable = ./../Traversable/Type + +in let extractFunctor = ./../Traversable/extractFunctor + +in let Applicative = ./../Applicative/Type + +in let Either = ./../Either/Type + +in λ(f : Type → Type) + → λ(c : ./Type f) + → λ(traversable : Traversable f) + → λ(g : Type → Type) + → λ(applicative : Applicative g) + → λ(a : Type) + → λ(b : Type) + → λ(k : a → g (Either a b)) + → λ(fa : f a) + → applicative.map + (f (Either a b)) + { _1 : f a, _2 : f b } + (c.separate (extractFunctor f traversable) a b) + (traversable.traverse g applicative a (Either a b) k fa) diff --git a/Compactable/traverseMaybe b/Compactable/traverseMaybe new file mode 100644 index 0000000..7069944 --- /dev/null +++ b/Compactable/traverseMaybe @@ -0,0 +1,20 @@ + let Traversable = ./../Traversable/Type + +in let extractFunctor = ./../Traversable/extractFunctor + +in let Applicative = ./../Applicative/Type + +in λ(f : Type → Type) + → λ(c : ./Type f) + → λ(traversable : Traversable f) + → λ(g : Type → Type) + → λ(applicative : Applicative g) + → λ(a : Type) + → λ(b : Type) + → λ(k : a → g (Optional b)) + → λ(fa : f a) + → applicative.map + (f (Optional b)) + (f b) + (c.compact (extractFunctor f traversable) b) + (traversable.traverse g applicative a (Optional b) k fa) From 53e0a1fb177bb8c945ce8e507d3127574cd652e6 Mon Sep 17 00:00:00 2001 From: FintanH Date: Sat, 2 Feb 2019 14:29:04 +0000 Subject: [PATCH 08/25] Use anonymous tuple syntax --- Either/lefts | 2 +- Either/partition | 57 +++++++++++++++++++----------------------------- Either/rights | 2 +- 3 files changed, 24 insertions(+), 37 deletions(-) diff --git a/Either/lefts b/Either/lefts index fab489b..1bb6802 100644 --- a/Either/lefts +++ b/Either/lefts @@ -3,4 +3,4 @@ in λ(a : Type) → λ(b : Type) → λ(eithers : List (Either a b)) - → (./partition a b eithers).lefts + → (./partition a b eithers)._1 diff --git a/Either/partition b/Either/partition index a289e40..e2a53af 100644 --- a/Either/partition +++ b/Either/partition @@ -1,37 +1,24 @@ let Either = ./Type -in let partition - : ∀(a : Type) - → ∀(b : Type) - → List (Either a b) - → { lefts : List a, rights : List b } - = λ(a : Type) - → λ(b : Type) - → λ(eithers : List (Either a b)) - → let left = - λ(acc : { lefts : List a, rights : List b }) - → λ(x : a) - → { lefts = [ x ] # acc.lefts, rights = acc.rights } - - in let right = - λ(acc : { lefts : List a, rights : List b }) - → λ(y : b) - → { lefts = acc.lefts, rights = [ y ] # acc.rights } - - in List/fold - (Either a b) - eithers - { lefts : List a, rights : List b } - ( λ(e : Either a b) - → λ(acc : { lefts : List a, rights : List b }) - → ./fold - a - b - { lefts : List a, rights : List b } - (left acc) - (right acc) - e - ) - { lefts = [] : List a, rights = [] : List b } - -in partition +in λ(a : Type) + → λ(b : Type) + → λ(eithers : List (Either a b)) + → let left = + λ(acc : { _1 : List a, _2 : List b }) + → λ(x : a) + → { _1 = [ x ] # acc._1, _2 = acc._2 } + + in let right = + λ(acc : { _1 : List a, _2 : List b }) + → λ(y : b) + → { _1 = acc._1, _2 = [ y ] # acc._2 } + + in List/fold + (Either a b) + eithers + { _1 : List a, _2 : List b } + ( λ(e : Either a b) + → λ(acc : { _1 : List a, _2 : List b }) + → ./fold a b { _1 : List a, _2 : List b } (left acc) (right acc) e + ) + { _1 = [] : List a, _2 = [] : List b } diff --git a/Either/rights b/Either/rights index 39520b9..72ab630 100644 --- a/Either/rights +++ b/Either/rights @@ -3,4 +3,4 @@ in λ(a : Type) → λ(b : Type) → λ(eithers : List (Either a b)) - → (./partition a b eithers).rights + → (./partition a b eithers)._2 From 86b5f2ae1aa3dc2e1985a0be85ecde01800e6999 Mon Sep 17 00:00:00 2001 From: FintanH Date: Sat, 2 Feb 2019 14:30:03 +0000 Subject: [PATCH 09/25] Clean up compactable representation --- Compactable/Type | 10 ++-------- Compactable/apEither | 8 +------- Compactable/apMaybe | 7 +------ Compactable/bindEither | 4 +--- Compactable/bindMaybe | 4 +--- Compactable/fromSeparate | 11 +++-------- Compactable/mapEither | 2 +- Compactable/mapMaybe | 2 +- Compactable/traverseEither | 4 +--- Compactable/traverseMaybe | 4 +--- 10 files changed, 13 insertions(+), 43 deletions(-) diff --git a/Compactable/Type b/Compactable/Type index 86ac283..8ca1293 100644 --- a/Compactable/Type +++ b/Compactable/Type @@ -1,14 +1,8 @@ let Either = ./../Either/Type -in let Functor = ./../Functor/Type - in λ(f : Type → Type) → { compact : - ∀(functor : Functor f) → ∀(a : Type) → f (Optional a) → f a + ∀(a : Type) → f (Optional a) → f a , separate : - ∀(functor : Functor f) - → ∀(a : Type) - → ∀(b : Type) - → f (Either a b) - → { _1 : f a, _2 : f b } + ∀(a : Type) → ∀(b : Type) → f (Either a b) → { _1 : f a, _2 : f b } } diff --git a/Compactable/apEither b/Compactable/apEither index 3b08e9e..b81b231 100644 --- a/Compactable/apEither +++ b/Compactable/apEither @@ -1,7 +1,5 @@ let Applicative = ./../Applicative/Type -in let extractFunctor = ./../Applicative/extractFunctor - in let Either = ./../Either/Type in λ(f : Type → Type) @@ -11,8 +9,4 @@ in λ(f : Type → Type) → λ(b : Type) → λ(k : f (a → Either a b)) → λ(fa : f a) - → c.separate - (extractFunctor f applicative) - a - b - (applicative.ap a (Either a b) k fa) + → c.separate a b (applicative.ap a (Either a b) k fa) diff --git a/Compactable/apMaybe b/Compactable/apMaybe index 664ccc1..fd7efda 100644 --- a/Compactable/apMaybe +++ b/Compactable/apMaybe @@ -1,7 +1,5 @@ let Applicative = ./../Applicative/Type -in let extractFunctor = ./../Applicative/extractFunctor - in λ(f : Type → Type) → λ(c : ./Type f) → λ(applicative : Applicative f) @@ -9,7 +7,4 @@ in λ(f : Type → Type) → λ(b : Type) → λ(k : f (a → Optional b)) → λ(fa : f a) - → c.compact - (extractFunctor f applicative) - b - (applicative.ap a (Optional b) k fa) + → c.compact b (applicative.ap a (Optional b) k fa) diff --git a/Compactable/bindEither b/Compactable/bindEither index 2c74a44..6fbd9f2 100644 --- a/Compactable/bindEither +++ b/Compactable/bindEither @@ -1,7 +1,5 @@ let Monad = ./../Monad/Type -in let extractFunctor = ./../Monad/extractFunctor - in let Either = ./../Either/Type in λ(f : Type → Type) @@ -11,4 +9,4 @@ in λ(f : Type → Type) → λ(b : Type) → λ(k : a → f (Either a b)) → λ(fa : f a) - → c.separate (extractFunctor f monad) a b (monad.bind a (Either a b) fa k) + → c.separate a b (monad.bind a (Either a b) fa k) diff --git a/Compactable/bindMaybe b/Compactable/bindMaybe index 1c97216..22f170d 100644 --- a/Compactable/bindMaybe +++ b/Compactable/bindMaybe @@ -1,7 +1,5 @@ let Monad = ./../Monad/Type -in let extractFunctor = ./../Monad/extractFunctor - in λ(f : Type → Type) → λ(c : ./Type f) → λ(monad : Monad f) @@ -9,4 +7,4 @@ in λ(f : Type → Type) → λ(b : Type) → λ(k : a → f (Optional b)) → λ(fa : f a) - → c.compact (extractFunctor f monad) b (monad.bind a (Optional b) fa k) + → c.compact b (monad.bind a (Optional b) fa k) diff --git a/Compactable/fromSeparate b/Compactable/fromSeparate index 5a5b3b4..6282efa 100644 --- a/Compactable/fromSeparate +++ b/Compactable/fromSeparate @@ -3,23 +3,18 @@ in let Functor = ./../Functor/Type in λ(f : Type → Type) + → λ(functor : Functor f) → λ ( separate - : ∀(functor : Functor f) - → ∀(a : Type) - → ∀(b : Type) - → f (Either a b) - → { _1 : f a, _2 : f b } + : ∀(a : Type) → ∀(b : Type) → f (Either a b) → { _1 : f a, _2 : f b } ) → { separate = separate , compact = - λ(functor : Functor f) - → λ(a : Type) + λ(a : Type) → λ(optionals : f (Optional a)) → let E = constructors (Either a {}) in ( separate - functor a {} ( functor.map diff --git a/Compactable/mapEither b/Compactable/mapEither index 4218314..d42a09f 100644 --- a/Compactable/mapEither +++ b/Compactable/mapEither @@ -9,4 +9,4 @@ in λ(f : Type → Type) → λ(b : Type) → λ(k : a → Either a b) → λ(fa : f a) - → c.separate functor a b (functor.map a (Either a b) k fa) + → c.separate a b (functor.map a (Either a b) k fa) diff --git a/Compactable/mapMaybe b/Compactable/mapMaybe index 0a78f9e..d698533 100644 --- a/Compactable/mapMaybe +++ b/Compactable/mapMaybe @@ -7,4 +7,4 @@ in λ(f : Type → Type) → λ(b : Type) → λ(k : a → Optional b) → λ(fa : f a) - → c.compact functor b (functor.map a (Optional b) k fa) + → c.compact b (functor.map a (Optional b) k fa) diff --git a/Compactable/traverseEither b/Compactable/traverseEither index 84cf736..43c0ed5 100644 --- a/Compactable/traverseEither +++ b/Compactable/traverseEither @@ -1,7 +1,5 @@ let Traversable = ./../Traversable/Type -in let extractFunctor = ./../Traversable/extractFunctor - in let Applicative = ./../Applicative/Type in let Either = ./../Either/Type @@ -18,5 +16,5 @@ in λ(f : Type → Type) → applicative.map (f (Either a b)) { _1 : f a, _2 : f b } - (c.separate (extractFunctor f traversable) a b) + (c.separate a b) (traversable.traverse g applicative a (Either a b) k fa) diff --git a/Compactable/traverseMaybe b/Compactable/traverseMaybe index 7069944..c8d4de2 100644 --- a/Compactable/traverseMaybe +++ b/Compactable/traverseMaybe @@ -1,7 +1,5 @@ let Traversable = ./../Traversable/Type -in let extractFunctor = ./../Traversable/extractFunctor - in let Applicative = ./../Applicative/Type in λ(f : Type → Type) @@ -16,5 +14,5 @@ in λ(f : Type → Type) → applicative.map (f (Optional b)) (f b) - (c.compact (extractFunctor f traversable) b) + (c.compact b) (traversable.traverse g applicative a (Optional b) k fa) From eb27c3c70042074b8ad35da59071560331252aab Mon Sep 17 00:00:00 2001 From: FintanH Date: Sat, 2 Feb 2019 14:30:21 +0000 Subject: [PATCH 10/25] List compactable instance --- List/compactable | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 List/compactable diff --git a/List/compactable b/List/compactable new file mode 100644 index 0000000..5f17985 --- /dev/null +++ b/List/compactable @@ -0,0 +1,5 @@ + ./../Compactable/fromSeparate + List + ./functor + (λ(a : Type) → λ(b : Type) → ./../Either/partition a b) +: ./../Compactable/Type List From 5473be05cc9c0dc268b6d12cb9705ad174d246af Mon Sep 17 00:00:00 2001 From: FintanH Date: Sat, 2 Feb 2019 16:24:49 +0000 Subject: [PATCH 11/25] Fix fromCompact --- Compactable/fromCompact | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Compactable/fromCompact b/Compactable/fromCompact index ef69cf6..80d01b6 100644 --- a/Compactable/fromCompact +++ b/Compactable/fromCompact @@ -7,7 +7,8 @@ in let flipEither = ./../Either/flipEither in let hush = ./../Either/hush in λ(f : Type → Type) - → λ(compact : ∀(functor : Functor f) → ∀(a : Type) → f (Optional a) → f a) + → λ(functor : Functor f) + → λ(compact : ∀(a : Type) → f (Optional a) → f a) → { compact = compact , separate = @@ -17,7 +18,6 @@ in λ(f : Type → Type) → λ(eithers : f (Either a b)) → { _1 = compact - functor a ( functor.map (Either a b) @@ -27,7 +27,6 @@ in λ(f : Type → Type) ) , _2 = compact - functor b (functor.map (Either a b) (Optional b) (hush a b) eithers) } From 9e301470e9a322c0caf0704aa37b076e7dbbce7b Mon Sep 17 00:00:00 2001 From: FintanH Date: Sat, 2 Feb 2019 16:25:03 +0000 Subject: [PATCH 12/25] Add Optional instance --- Optional/compactable | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 Optional/compactable diff --git a/Optional/compactable b/Optional/compactable new file mode 100644 index 0000000..0d1b3d6 --- /dev/null +++ b/Optional/compactable @@ -0,0 +1,6 @@ + let join = (./../Monad/package.dhall Optional ./monad).join + +in ./../Compactable/fromCompact + Optional + ./functor + (λ(a : Type) → λ(o : Optional (Optional a)) → join a o) From 8dca13e7606704dbae3b6a1325655f1a23818e0c Mon Sep 17 00:00:00 2001 From: FintanH Date: Sat, 2 Feb 2019 17:30:21 +0000 Subject: [PATCH 13/25] Added Either instance --- Either/compactable | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 Either/compactable diff --git a/Either/compactable b/Either/compactable new file mode 100644 index 0000000..372b271 --- /dev/null +++ b/Either/compactable @@ -0,0 +1,31 @@ + let Either = ./Type + +in let Monoid = ./../Monoid/Type + +in λ(m : Type) + → λ(monoid : Monoid m) + → ./../Compactable/fromSeparate + (Either m) + (./functor m) + ( λ(a : Type) + → λ(b : Type) + → λ(e : Either m (Either a b)) + → let EB = constructors (Either m b) + + in let EA = constructors (Either m a) + + in merge + { Left = + λ(x : m) → { _1 = EA.Left x, _2 = EB.Left x } + , Right = + λ(ee : Either a b) + → merge + { Left = + λ(l : a) → { _1 = EA.Right l, _2 = EB.Left monoid.unit } + , Right = + λ(r : b) → { _1 = EA.Left monoid.unit, _2 = EB.Right r } + } + ee + } + e + ) From b744ae76790306d830ecf5f038f6ecdb7fd4b773 Mon Sep 17 00:00:00 2001 From: FintanH Date: Sat, 2 Feb 2019 20:04:18 +0000 Subject: [PATCH 14/25] Rename Maybe to Optional --- Compactable/{apMaybe => apOptional} | 0 Compactable/{bindMaybe => bindOptional} | 0 Compactable/{mapMaybe => mapOptional} | 0 Compactable/{traverseMaybe => traverseOptional} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename Compactable/{apMaybe => apOptional} (100%) rename Compactable/{bindMaybe => bindOptional} (100%) rename Compactable/{mapMaybe => mapOptional} (100%) rename Compactable/{traverseMaybe => traverseOptional} (100%) diff --git a/Compactable/apMaybe b/Compactable/apOptional similarity index 100% rename from Compactable/apMaybe rename to Compactable/apOptional diff --git a/Compactable/bindMaybe b/Compactable/bindOptional similarity index 100% rename from Compactable/bindMaybe rename to Compactable/bindOptional diff --git a/Compactable/mapMaybe b/Compactable/mapOptional similarity index 100% rename from Compactable/mapMaybe rename to Compactable/mapOptional diff --git a/Compactable/traverseMaybe b/Compactable/traverseOptional similarity index 100% rename from Compactable/traverseMaybe rename to Compactable/traverseOptional From ad3b3fa27147024ce73fb8a609198c9146df9802 Mon Sep 17 00:00:00 2001 From: FintanH Date: Sat, 2 Feb 2019 20:33:21 +0000 Subject: [PATCH 15/25] Fix fromCompact and annotate instances --- Compactable/fromCompact | 3 +-- Either/compactable | 53 ++++++++++++++++++++++------------------- Optional/compactable | 9 +++---- 3 files changed, 34 insertions(+), 31 deletions(-) diff --git a/Compactable/fromCompact b/Compactable/fromCompact index 80d01b6..76a1d3f 100644 --- a/Compactable/fromCompact +++ b/Compactable/fromCompact @@ -12,8 +12,7 @@ in λ(f : Type → Type) → { compact = compact , separate = - λ(functor : Functor f) - → λ(a : Type) + λ(a : Type) → λ(b : Type) → λ(eithers : f (Either a b)) → { _1 = diff --git a/Either/compactable b/Either/compactable index 372b271..550b1f5 100644 --- a/Either/compactable +++ b/Either/compactable @@ -4,28 +4,31 @@ in let Monoid = ./../Monoid/Type in λ(m : Type) → λ(monoid : Monoid m) - → ./../Compactable/fromSeparate - (Either m) - (./functor m) - ( λ(a : Type) - → λ(b : Type) - → λ(e : Either m (Either a b)) - → let EB = constructors (Either m b) - - in let EA = constructors (Either m a) - - in merge - { Left = - λ(x : m) → { _1 = EA.Left x, _2 = EB.Left x } - , Right = - λ(ee : Either a b) - → merge - { Left = - λ(l : a) → { _1 = EA.Right l, _2 = EB.Left monoid.unit } - , Right = - λ(r : b) → { _1 = EA.Left monoid.unit, _2 = EB.Right r } - } - ee - } - e - ) + → ./../Compactable/fromSeparate + (Either m) + (./functor m) + ( λ(a : Type) + → λ(b : Type) + → λ(e : Either m (Either a b)) + → let EB = constructors (Either m b) + + in let EA = constructors (Either m a) + + in merge + { Left = + λ(x : m) → { _1 = EA.Left x, _2 = EB.Left x } + , Right = + λ(ee : Either a b) + → merge + { Left = + λ(l : a) + → { _1 = EA.Right l, _2 = EB.Left monoid.unit } + , Right = + λ(r : b) + → { _1 = EA.Left monoid.unit, _2 = EB.Right r } + } + ee + } + e + ) + : ./../Compactable/Type (Either m) diff --git a/Optional/compactable b/Optional/compactable index 0d1b3d6..31f084a 100644 --- a/Optional/compactable +++ b/Optional/compactable @@ -1,6 +1,7 @@ let join = (./../Monad/package.dhall Optional ./monad).join -in ./../Compactable/fromCompact - Optional - ./functor - (λ(a : Type) → λ(o : Optional (Optional a)) → join a o) +in ./../Compactable/fromCompact + Optional + ./functor + (λ(a : Type) → λ(o : Optional (Optional a)) → join a o) + : ./../Compactable/Type Optional From d91d645fb7b621df597ed36d74d61c4593ced845 Mon Sep 17 00:00:00 2001 From: FintanH Date: Sat, 2 Feb 2019 20:33:31 +0000 Subject: [PATCH 16/25] Document Compactable/Type --- Compactable/Type | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Compactable/Type b/Compactable/Type index 8ca1293..28fc93a 100644 --- a/Compactable/Type +++ b/Compactable/Type @@ -1,3 +1,18 @@ +{- +Compactable serves as an abstraction over filtering and partitioning, using two functions +compact and separate, respectively. + +Both functions work over some higher kind f (Type -> Type). + +compact works over the f when it is fully applied with an Optional type. It filters out None +values, leaving only the values contained in the Some values. + +separate works over the f when it is fully applied with an Either type. It partitions Left +values to the _1 element of a tuple, and Right values to the _2 element of a tuple. + +Since both functions can be written in terms of the other, we can create instances by choosing one +of the function fromCompact or fromSeparate. +-} let Either = ./../Either/Type in λ(f : Type → Type) From 4e105fda22c653fe208595ddd68f41dc99b45ed3 Mon Sep 17 00:00:00 2001 From: FintanH Date: Sat, 2 Feb 2019 20:46:46 +0000 Subject: [PATCH 17/25] Document from functions --- Compactable/fromCompact | 6 ++++++ Compactable/fromSeparate | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/Compactable/fromCompact b/Compactable/fromCompact index 76a1d3f..a7ae9e9 100644 --- a/Compactable/fromCompact +++ b/Compactable/fromCompact @@ -1,3 +1,9 @@ +{- +fromCompact gives a Compactable instance by supplying a functor instance for f and the compact function. + +`separate` can be defined by mapping over `f (Either a b)` and `f (Either b a)`, using `hush` to convert to +an `Optional` and compact to convert to `f a` and `f b`, respectively. +-} let Either = ./../Either/Type in let Functor = ./../Functor/Type diff --git a/Compactable/fromSeparate b/Compactable/fromSeparate index 6282efa..62f31dd 100644 --- a/Compactable/fromSeparate +++ b/Compactable/fromSeparate @@ -1,3 +1,9 @@ +{- +fromSeparate gives a Compactable instance by supplying a functor instance for f and the separate function. + +`compact` can be defined by converting `Option a` into `Either a {}`, using `separate` and take the `_1` +element from the tuple. +-} let Either = ./../Either/Type in let Functor = ./../Functor/Type From c89d4c46ef3dd13a294305b71e2455af819f8eba Mon Sep 17 00:00:00 2001 From: FintanH Date: Sat, 2 Feb 2019 21:12:24 +0000 Subject: [PATCH 18/25] Fix spacing, add docs and examples to map and ap functions --- Compactable/Type | 2 ++ Compactable/apOptional | 23 +++++++++++++++++++++++ Compactable/fromCompact | 2 ++ Compactable/fromSeparate | 2 ++ Compactable/mapEither | 21 +++++++++++++++++++++ Compactable/mapOptional | 19 +++++++++++++++++++ 6 files changed, 69 insertions(+) diff --git a/Compactable/Type b/Compactable/Type index 28fc93a..76ac249 100644 --- a/Compactable/Type +++ b/Compactable/Type @@ -1,4 +1,5 @@ {- + Compactable serves as an abstraction over filtering and partitioning, using two functions compact and separate, respectively. @@ -12,6 +13,7 @@ values to the _1 element of a tuple, and Right values to the _2 element of a tup Since both functions can be written in terms of the other, we can create instances by choosing one of the function fromCompact or fromSeparate. + -} let Either = ./../Either/Type diff --git a/Compactable/apOptional b/Compactable/apOptional index fd7efda..3a2e0db 100644 --- a/Compactable/apOptional +++ b/Compactable/apOptional @@ -1,3 +1,26 @@ +{- + +mapOptional maps a function to Optionals over the `f` and `compact`s away the `None` values. + +Examples: + +``` + let E = constructors (./Either/Type Natural Natural) + +in ./Compactable/apEither + List + ./List/compactable + ./List/applicative + Natural + Natural + [ λ(n : Natural) → if Natural/even n then E.Left n else E.Right n + , λ(n : Natural) → if Natural/odd n then E.Left n else E.Right n + ] + [ 0, 1, 2, 3, 4, 5 ] += { _1 = [ 0, 2, 4, 1, 3, 5 ], _2 = [ 1, 3, 5, 0, 2, 4 ] } +``` + +-} let Applicative = ./../Applicative/Type in λ(f : Type → Type) diff --git a/Compactable/fromCompact b/Compactable/fromCompact index a7ae9e9..efbe858 100644 --- a/Compactable/fromCompact +++ b/Compactable/fromCompact @@ -1,8 +1,10 @@ {- + fromCompact gives a Compactable instance by supplying a functor instance for f and the compact function. `separate` can be defined by mapping over `f (Either a b)` and `f (Either b a)`, using `hush` to convert to an `Optional` and compact to convert to `f a` and `f b`, respectively. + -} let Either = ./../Either/Type diff --git a/Compactable/fromSeparate b/Compactable/fromSeparate index 62f31dd..a497ac8 100644 --- a/Compactable/fromSeparate +++ b/Compactable/fromSeparate @@ -1,8 +1,10 @@ {- + fromSeparate gives a Compactable instance by supplying a functor instance for f and the separate function. `compact` can be defined by converting `Option a` into `Either a {}`, using `separate` and take the `_1` element from the tuple. + -} let Either = ./../Either/Type diff --git a/Compactable/mapEither b/Compactable/mapEither index d42a09f..f7ecc4a 100644 --- a/Compactable/mapEither +++ b/Compactable/mapEither @@ -1,3 +1,24 @@ +{- + +mapEither maps a function to Either over the `f` and `separate`s `Left`s from `Right`s. + +Examples: + +``` + let E = constructors (./Either/Type Natural Natural) + +in ./Compactable/mapEither + List + ./List/compactable + ./List/functor + Natural + Natural + (λ(n : Natural) → if Natural/even n then E.Left n else E.Right n) + [ 1, 2, 3, 4, 5 ] += { _1 = [ 2, 4 ], _2 = [ 1, 3, 5 ] } +``` + +-} let Functor = ./../Functor/Type in let Either = ./../Either/Type diff --git a/Compactable/mapOptional b/Compactable/mapOptional index d698533..a7cd919 100644 --- a/Compactable/mapOptional +++ b/Compactable/mapOptional @@ -1,3 +1,22 @@ +{- + +mapOptional maps a function to Optionals over the `f` and `compact`s away the `None` values. + +Examples: + +``` +./Compactable/mapOptional +List +./List/compactable +./List/functor +Natural +Natural +(λ(n : Natural) → if Natural/even n then Some n else None Natural) +[ 1, 2, 3, 4, 5 ] += [ 2, 4 ] +``` + +-} let Functor = ./../Functor/Type in λ(f : Type → Type) From 582df5ec0a91c0f7b191ff17136efa412cd9ecca Mon Sep 17 00:00:00 2001 From: FintanH Date: Sat, 2 Feb 2019 21:19:41 +0000 Subject: [PATCH 19/25] Fix ap docs --- Compactable/apEither | 18 ++++++++++++++++++ Compactable/apOptional | 26 ++++++++++++-------------- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/Compactable/apEither b/Compactable/apEither index b81b231..d6366e3 100644 --- a/Compactable/apEither +++ b/Compactable/apEither @@ -1,3 +1,21 @@ +{- +apEither maps an `f` of functions to Eithers over the `f a` and `separate`s `Left`s from `Right`s. + + let E = constructors (./Either/Type Natural Natural) + +in ./Compactable/apEither + List + ./List/compactable + ./List/applicative + Natural + Natural + [ λ(n : Natural) → if Natural/even n then E.Left n else E.Right n + , λ(n : Natural) → if Natural/odd n then E.Left n else E.Right n + ] + [ 0, 1, 2, 3, 4, 5 ] += { _1 = [ 0, 2, 4, 1, 3, 5 ], _2 = [ 1, 3, 5, 0, 2, 4 ] } + +-} let Applicative = ./../Applicative/Type in let Either = ./../Either/Type diff --git a/Compactable/apOptional b/Compactable/apOptional index 3a2e0db..45599bb 100644 --- a/Compactable/apOptional +++ b/Compactable/apOptional @@ -1,23 +1,21 @@ {- -mapOptional maps a function to Optionals over the `f` and `compact`s away the `None` values. +apOptional maps a `f` of functions to Optionals over the `f` and `compact`s away the `None` values. Examples: ``` - let E = constructors (./Either/Type Natural Natural) - -in ./Compactable/apEither - List - ./List/compactable - ./List/applicative - Natural - Natural - [ λ(n : Natural) → if Natural/even n then E.Left n else E.Right n - , λ(n : Natural) → if Natural/odd n then E.Left n else E.Right n - ] - [ 0, 1, 2, 3, 4, 5 ] -= { _1 = [ 0, 2, 4, 1, 3, 5 ], _2 = [ 1, 3, 5, 0, 2, 4 ] } +./Compactable/apOptional +List +./List/compactable +./List/applicative +Natural +Natural +[ λ(n : Natural) → if Natural/even n then Some n else None Natural +, λ(n : Natural) → if Natural/odd n then Some n else None Natural +] +[ 0, 1, 2, 3, 4, 5 ] += [ 0, 2, 4, 1, 3, 5 ] ``` -} From f83ae8690fd039b139a80bb0f13f4cf5939e8400 Mon Sep 17 00:00:00 2001 From: FintanH Date: Sat, 2 Feb 2019 21:33:41 +0000 Subject: [PATCH 20/25] Add bind docs --- Compactable/bindEither | 32 ++++++++++++++++++++++++++++++++ Compactable/bindOptional | 28 ++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/Compactable/bindEither b/Compactable/bindEither index 6fbd9f2..3a09841 100644 --- a/Compactable/bindEither +++ b/Compactable/bindEither @@ -1,3 +1,35 @@ +{- + +bindEither binds to a `f` of Optional over the `f a` and `separate`s `Left`s and `Right`s. + +Examples: + +``` + let replicate = + https://raw.githubusercontent.com/dhall-lang/dhall-lang/master/Prelude/List/replicate + +in let Either = ./Either/Type + +in let E = constructors (Either Natural Natural) + +in ./Compactable/bindEither + List + ./List/compactable + ./List/monad + Natural + Natural + ( λ(n : Natural) + → if Natural/even n + + then replicate n (Either Natural Natural) (E.Left n) + + else replicate n (Either Natural Natural) (E.Right n) + ) + [ 0, 1, 2, 3, 4, 5 ] += { _1 = [ 2, 2, 4, 4, 4, 4 ], _2 = [ 1, 3, 3, 3, 5, 5, 5, 5, 5 ] } +``` + +-} let Monad = ./../Monad/Type in let Either = ./../Either/Type diff --git a/Compactable/bindOptional b/Compactable/bindOptional index 22f170d..c5e7213 100644 --- a/Compactable/bindOptional +++ b/Compactable/bindOptional @@ -1,3 +1,31 @@ +{- + +bindOptional binds to a `f` of Optional over the `f a` and `compact`s away the `None` values. + +Examples: + +``` + let replicate = + https://raw.githubusercontent.com/dhall-lang/dhall-lang/master/Prelude/List/replicate + +in ./Compactable/bindOptional + List + ./List/compactable + ./List/monad + Natural + Natural + ( λ(n : Natural) + → if Natural/even n + + then replicate n (Optional Natural) (Some n) + + else [] : List (Optional Natural) + ) + [ 0, 1, 2, 3, 4, 5 ] += [ 2, 2, 4, 4, 4, 4 ] +``` + +-} let Monad = ./../Monad/Type in λ(f : Type → Type) From 780de73a694ddf88b2cdae64fdd9e305dd61656c Mon Sep 17 00:00:00 2001 From: FintanH Date: Sat, 2 Feb 2019 21:49:41 +0000 Subject: [PATCH 21/25] Document flipEither and hush --- Either/flipEither | 23 +++++++++++++++++++++++ Either/hush | 24 ++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/Either/flipEither b/Either/flipEither index 2ec6c3a..02aa7c7 100644 --- a/Either/flipEither +++ b/Either/flipEither @@ -1,3 +1,26 @@ +{- + +Flip the value of an Either where `Right` goes to `Left`, and `Left` goes to `Right`. + +Examples: +``` + let Either = ./Either/Type + +in let E = constructors (Either Text Natural) + +in ./Either/flipEither Text Natural (E.Left "ohno") += < Right = "ohno" | Left : Natural > + + + let Either = ./Either/Type + +in let E = constructors (Either Text Natural) + +in ./Either/flipEither Text Natural (E.Right 42) += < Left = 42 | Right : Text > +``` + +-} let Either = ./Type in λ(a : Type) diff --git a/Either/hush b/Either/hush index e9b3efe..67f029c 100644 --- a/Either/hush +++ b/Either/hush @@ -1,3 +1,27 @@ +{- + +Turns an `Either a b` into an `Optional b` by hushing `Left` values to `None` and +converting `Right` values to `Some`. + +Examples: +``` + let Either = ./Either/Type + +in let E = constructors (Either Text Natural) + +in ./Either/hush Text Natural (E.Right 42) += Some 42 + + + let Either = ./Either/Type + +in let E = constructors (Either Text Natural) + +in ./Either/hush Text Natural (E.Left "ohno") += None Natural +``` + +-} λ(a : Type) → λ(b : Type) → ./fold a b (Optional b) (λ(_ : a) → None b) (λ(x : b) → Some x) From 12ee10e630fe327b6aff379eaa081871835f9113 Mon Sep 17 00:00:00 2001 From: FintanH Date: Mon, 4 Feb 2019 14:16:01 +0000 Subject: [PATCH 22/25] Make typeclass method be mapOptional and mapEither --- Compactable/Type | 13 +++++--- Compactable/apEither | 2 +- Compactable/apOptional | 2 +- Compactable/bindEither | 2 +- Compactable/bindOptional | 2 +- Compactable/{mapOptional => compact} | 14 +++----- Compactable/fromCompact | 40 ---------------------- Compactable/fromMapEither | 50 ++++++++++++++++++++++++++++ Compactable/fromMapOptional | 47 ++++++++++++++++++++++++++ Compactable/fromSeparate | 42 ----------------------- Compactable/{mapEither => separate} | 19 ++++++----- Compactable/traverseEither | 2 +- Compactable/traverseOptional | 2 +- Either/compactable | 30 +++++++++-------- List/compactable | 27 ++++++++++++--- Optional/compactable | 12 ++++--- 16 files changed, 173 insertions(+), 133 deletions(-) rename Compactable/{mapOptional => compact} (52%) delete mode 100644 Compactable/fromCompact create mode 100644 Compactable/fromMapEither create mode 100644 Compactable/fromMapOptional delete mode 100644 Compactable/fromSeparate rename Compactable/{mapEither => separate} (64%) diff --git a/Compactable/Type b/Compactable/Type index 76ac249..193620d 100644 --- a/Compactable/Type +++ b/Compactable/Type @@ -18,8 +18,13 @@ of the function fromCompact or fromSeparate. let Either = ./../Either/Type in λ(f : Type → Type) - → { compact : - ∀(a : Type) → f (Optional a) → f a - , separate : - ∀(a : Type) → ∀(b : Type) → f (Either a b) → { _1 : f a, _2 : f b } + → { mapOptional : + ∀(a : Type) → ∀(b : Type) → (a → Optional b) → f a → f b + , mapEither : + ∀(a : Type) + → ∀(l : Type) + → ∀(r : Type) + → (a → Either l r) + → f a + → { _1 : f l, _2 : f r } } diff --git a/Compactable/apEither b/Compactable/apEither index d6366e3..bc65d16 100644 --- a/Compactable/apEither +++ b/Compactable/apEither @@ -27,4 +27,4 @@ in λ(f : Type → Type) → λ(b : Type) → λ(k : f (a → Either a b)) → λ(fa : f a) - → c.separate a b (applicative.ap a (Either a b) k fa) + → ./separate f c a b (applicative.ap a (Either a b) k fa) diff --git a/Compactable/apOptional b/Compactable/apOptional index 45599bb..b9c07d6 100644 --- a/Compactable/apOptional +++ b/Compactable/apOptional @@ -28,4 +28,4 @@ in λ(f : Type → Type) → λ(b : Type) → λ(k : f (a → Optional b)) → λ(fa : f a) - → c.compact b (applicative.ap a (Optional b) k fa) + → ./compact f c b (applicative.ap a (Optional b) k fa) diff --git a/Compactable/bindEither b/Compactable/bindEither index 3a09841..19655c4 100644 --- a/Compactable/bindEither +++ b/Compactable/bindEither @@ -41,4 +41,4 @@ in λ(f : Type → Type) → λ(b : Type) → λ(k : a → f (Either a b)) → λ(fa : f a) - → c.separate a b (monad.bind a (Either a b) fa k) + → ./separate f c a b (monad.bind a (Either a b) fa k) diff --git a/Compactable/bindOptional b/Compactable/bindOptional index c5e7213..310464b 100644 --- a/Compactable/bindOptional +++ b/Compactable/bindOptional @@ -35,4 +35,4 @@ in λ(f : Type → Type) → λ(b : Type) → λ(k : a → f (Optional b)) → λ(fa : f a) - → c.compact b (monad.bind a (Optional b) fa k) + → ./compact f c b (monad.bind a (Optional b) fa k) diff --git a/Compactable/mapOptional b/Compactable/compact similarity index 52% rename from Compactable/mapOptional rename to Compactable/compact index a7cd919..df84f9b 100644 --- a/Compactable/mapOptional +++ b/Compactable/compact @@ -17,13 +17,7 @@ Natural ``` -} - let Functor = ./../Functor/Type - -in λ(f : Type → Type) - → λ(c : ./Type f) - → λ(functor : Functor f) - → λ(a : Type) - → λ(b : Type) - → λ(k : a → Optional b) - → λ(fa : f a) - → c.compact b (functor.map a (Optional b) k fa) + λ(f : Type → Type) +→ λ(c : ./Type f) +→ λ(a : Type) +→ c.mapOptional (Optional a) a ((./../Function/category).identity (Optional a)) diff --git a/Compactable/fromCompact b/Compactable/fromCompact deleted file mode 100644 index efbe858..0000000 --- a/Compactable/fromCompact +++ /dev/null @@ -1,40 +0,0 @@ -{- - -fromCompact gives a Compactable instance by supplying a functor instance for f and the compact function. - -`separate` can be defined by mapping over `f (Either a b)` and `f (Either b a)`, using `hush` to convert to -an `Optional` and compact to convert to `f a` and `f b`, respectively. - --} - let Either = ./../Either/Type - -in let Functor = ./../Functor/Type - -in let flipEither = ./../Either/flipEither - -in let hush = ./../Either/hush - -in λ(f : Type → Type) - → λ(functor : Functor f) - → λ(compact : ∀(a : Type) → f (Optional a) → f a) - → { compact = - compact - , separate = - λ(a : Type) - → λ(b : Type) - → λ(eithers : f (Either a b)) - → { _1 = - compact - a - ( functor.map - (Either a b) - (Optional a) - (λ(either : Either a b) → hush b a (flipEither a b either)) - eithers - ) - , _2 = - compact - b - (functor.map (Either a b) (Optional b) (hush a b) eithers) - } - } diff --git a/Compactable/fromMapEither b/Compactable/fromMapEither new file mode 100644 index 0000000..166c304 --- /dev/null +++ b/Compactable/fromMapEither @@ -0,0 +1,50 @@ +{- + +fromSeparate gives a Compactable instance by supplying a functor instance for f and the separate function. + +`compact` can be defined by converting `Option a` into `Either a {}`, using `separate` and take the `_1` +element from the tuple. + +-} + let Either = ./../Either/Type + +in λ(f : Type → Type) + → λ ( mapEither + : ∀(a : Type) + → ∀(l : Type) + → ∀(r : Type) + → (a → Either l r) + → f a + → { _1 : f l, _2 : f r } + ) + → { mapEither = + mapEither + , mapOptional = + λ(a : Type) + → λ(b : Type) + → λ(k : a → Optional b) + → λ(fa : f a) + → let E = constructors (Either {} b) + + in ( mapEither + a + {} + b + ( (./../Function/category).compose + a + (Optional b) + (Either {} b) + ( λ(optional : Optional b) + → Optional/fold + b + optional + (Either {} b) + E.Right + (E.Left {=}) + ) + k + ) + fa + )._2 + } + : ./Type f diff --git a/Compactable/fromMapOptional b/Compactable/fromMapOptional new file mode 100644 index 0000000..fdc45ed --- /dev/null +++ b/Compactable/fromMapOptional @@ -0,0 +1,47 @@ +{- + +fromCompact gives a Compactable instance by supplying a functor instance for f and the compact function. + +`separate` can be defined by mapping over `f (Either a b)` and `f (Either b a)`, using `hush` to convert to +an `Optional` and compact to convert to `f a` and `f b`, respectively. + +-} + let Either = ./../Either/Type + +in let flipEither = ./../Either/flipEither + +in let hush = ./../Either/hush + +in let compose = (./../Function/category).compose + +in λ(f : Type → Type) + → λ(mapOptional : ∀(a : Type) → ∀(b : Type) → (a → Optional b) → f a → f b) + → { mapOptional = + mapOptional + , mapEither = + λ(a : Type) + → λ(l : Type) + → λ(r : Type) + → λ(k : a → Either l r) + → λ(fa : f a) + → { _1 = + mapOptional + a + l + ( compose + a + (Either r l) + (Optional l) + (hush r l) + (compose a (Either l r) (Either r l) (flipEither l r) k) + ) + fa + , _2 = + mapOptional + a + r + (compose a (Either l r) (Optional r) (hush l r) k) + fa + } + } + : ./Type f diff --git a/Compactable/fromSeparate b/Compactable/fromSeparate deleted file mode 100644 index a497ac8..0000000 --- a/Compactable/fromSeparate +++ /dev/null @@ -1,42 +0,0 @@ -{- - -fromSeparate gives a Compactable instance by supplying a functor instance for f and the separate function. - -`compact` can be defined by converting `Option a` into `Either a {}`, using `separate` and take the `_1` -element from the tuple. - --} - let Either = ./../Either/Type - -in let Functor = ./../Functor/Type - -in λ(f : Type → Type) - → λ(functor : Functor f) - → λ ( separate - : ∀(a : Type) → ∀(b : Type) → f (Either a b) → { _1 : f a, _2 : f b } - ) - → { separate = - separate - , compact = - λ(a : Type) - → λ(optionals : f (Optional a)) - → let E = constructors (Either a {}) - - in ( separate - a - {} - ( functor.map - (Optional a) - (Either a {}) - ( λ(optional : Optional a) - → Optional/fold - a - optional - (Either a {}) - E.Left - (E.Right {=}) - ) - optionals - ) - )._1 - } diff --git a/Compactable/mapEither b/Compactable/separate similarity index 64% rename from Compactable/mapEither rename to Compactable/separate index f7ecc4a..83c787a 100644 --- a/Compactable/mapEither +++ b/Compactable/separate @@ -19,15 +19,16 @@ in ./Compactable/mapEither ``` -} - let Functor = ./../Functor/Type - -in let Either = ./../Either/Type + let Either = ./../Either/Type in λ(f : Type → Type) → λ(c : ./Type f) - → λ(functor : Functor f) - → λ(a : Type) - → λ(b : Type) - → λ(k : a → Either a b) - → λ(fa : f a) - → c.separate a b (functor.map a (Either a b) k fa) + → λ(l : Type) + → λ(r : Type) + → λ(fa : f (Either l r)) + → c.mapEither + (Either l r) + l + r + ((./../Function/category).identity (Either l r)) + fa diff --git a/Compactable/traverseEither b/Compactable/traverseEither index 43c0ed5..e2e118b 100644 --- a/Compactable/traverseEither +++ b/Compactable/traverseEither @@ -16,5 +16,5 @@ in λ(f : Type → Type) → applicative.map (f (Either a b)) { _1 : f a, _2 : f b } - (c.separate a b) + (./separate f c a b) (traversable.traverse g applicative a (Either a b) k fa) diff --git a/Compactable/traverseOptional b/Compactable/traverseOptional index c8d4de2..fcabe08 100644 --- a/Compactable/traverseOptional +++ b/Compactable/traverseOptional @@ -14,5 +14,5 @@ in λ(f : Type → Type) → applicative.map (f (Optional b)) (f b) - (c.compact b) + (./compact f c b) (traversable.traverse g applicative a (Optional b) k fa) diff --git a/Either/compactable b/Either/compactable index 550b1f5..79c514f 100644 --- a/Either/compactable +++ b/Either/compactable @@ -1,33 +1,37 @@ +{- +mapEither : (a -> Either l r) -> Either m a -> { _1 : Either m l, _2 : Either m r } +-} let Either = ./Type in let Monoid = ./../Monoid/Type in λ(m : Type) → λ(monoid : Monoid m) - → ./../Compactable/fromSeparate + → ./../Compactable/fromMapEither (Either m) - (./functor m) ( λ(a : Type) - → λ(b : Type) - → λ(e : Either m (Either a b)) - → let EB = constructors (Either m b) + → λ(l : Type) + → λ(r : Type) + → λ(k : a → Either l r) + → λ(e : Either m a) + → let EL = constructors (Either m l) - in let EA = constructors (Either m a) + in let ER = constructors (Either m r) in merge { Left = - λ(x : m) → { _1 = EA.Left x, _2 = EB.Left x } + λ(x : m) → { _1 = EL.Left x, _2 = ER.Left x } , Right = - λ(ee : Either a b) + λ(x : a) → merge { Left = - λ(l : a) - → { _1 = EA.Right l, _2 = EB.Left monoid.unit } + λ(x : l) + → { _1 = EL.Right x, _2 = ER.Left monoid.unit } , Right = - λ(r : b) - → { _1 = EA.Left monoid.unit, _2 = EB.Right r } + λ(y : r) + → { _1 = EL.Left monoid.unit, _2 = ER.Right y } } - ee + (k x) } e ) diff --git a/List/compactable b/List/compactable index 5f17985..2192494 100644 --- a/List/compactable +++ b/List/compactable @@ -1,5 +1,22 @@ - ./../Compactable/fromSeparate - List - ./functor - (λ(a : Type) → λ(b : Type) → ./../Either/partition a b) -: ./../Compactable/Type List + let Either = ./../Either/Type + +in let compose = (./../Function/category).compose + +in let partition = ./../Either/partition + +in let map = (./functor).map + +in ./../Compactable/fromMapEither + List + ( λ(a : Type) + → λ(l : Type) + → λ(r : Type) + → λ(k : a → Either l r) + → compose + (List a) + (List (Either l r)) + { _1 : List l, _2 : List r } + (partition l r) + (map a (Either l r) k) + ) + : ./../Compactable/Type List diff --git a/Optional/compactable b/Optional/compactable index 31f084a..04df158 100644 --- a/Optional/compactable +++ b/Optional/compactable @@ -1,7 +1,11 @@ - let join = (./../Monad/package.dhall Optional ./monad).join + let bind = (./monad).bind -in ./../Compactable/fromCompact +in ./../Compactable/fromMapOptional Optional - ./functor - (λ(a : Type) → λ(o : Optional (Optional a)) → join a o) + ( λ(a : Type) + → λ(b : Type) + → λ(k : a → Optional b) + → λ(o : Optional a) + → bind a b o k + ) : ./../Compactable/Type Optional From 598e210a5688b049a8f081386b62db0d18a6a718 Mon Sep 17 00:00:00 2001 From: FintanH Date: Mon, 4 Feb 2019 16:44:46 +0000 Subject: [PATCH 23/25] Only use mapOptional. Clean up definitions --- Compactable/Type | 15 ++--------- Compactable/fromMapEither | 50 ------------------------------------ Compactable/fromMapOptional | 47 ---------------------------------- Compactable/separate | 27 +++++++++++++++----- Either/compactable | 51 ++++++++++++++++--------------------- List/compactable | 34 ++++++++++--------------- Optional/compactable | 15 +++++------ 7 files changed, 66 insertions(+), 173 deletions(-) delete mode 100644 Compactable/fromMapEither delete mode 100644 Compactable/fromMapOptional diff --git a/Compactable/Type b/Compactable/Type index 193620d..7009fe3 100644 --- a/Compactable/Type +++ b/Compactable/Type @@ -15,16 +15,5 @@ Since both functions can be written in terms of the other, we can create instanc of the function fromCompact or fromSeparate. -} - let Either = ./../Either/Type - -in λ(f : Type → Type) - → { mapOptional : - ∀(a : Type) → ∀(b : Type) → (a → Optional b) → f a → f b - , mapEither : - ∀(a : Type) - → ∀(l : Type) - → ∀(r : Type) - → (a → Either l r) - → f a - → { _1 : f l, _2 : f r } - } + λ(f : Type → Type) +→ { mapOptional : ∀(a : Type) → ∀(b : Type) → (a → Optional b) → f a → f b } diff --git a/Compactable/fromMapEither b/Compactable/fromMapEither deleted file mode 100644 index 166c304..0000000 --- a/Compactable/fromMapEither +++ /dev/null @@ -1,50 +0,0 @@ -{- - -fromSeparate gives a Compactable instance by supplying a functor instance for f and the separate function. - -`compact` can be defined by converting `Option a` into `Either a {}`, using `separate` and take the `_1` -element from the tuple. - --} - let Either = ./../Either/Type - -in λ(f : Type → Type) - → λ ( mapEither - : ∀(a : Type) - → ∀(l : Type) - → ∀(r : Type) - → (a → Either l r) - → f a - → { _1 : f l, _2 : f r } - ) - → { mapEither = - mapEither - , mapOptional = - λ(a : Type) - → λ(b : Type) - → λ(k : a → Optional b) - → λ(fa : f a) - → let E = constructors (Either {} b) - - in ( mapEither - a - {} - b - ( (./../Function/category).compose - a - (Optional b) - (Either {} b) - ( λ(optional : Optional b) - → Optional/fold - b - optional - (Either {} b) - E.Right - (E.Left {=}) - ) - k - ) - fa - )._2 - } - : ./Type f diff --git a/Compactable/fromMapOptional b/Compactable/fromMapOptional deleted file mode 100644 index fdc45ed..0000000 --- a/Compactable/fromMapOptional +++ /dev/null @@ -1,47 +0,0 @@ -{- - -fromCompact gives a Compactable instance by supplying a functor instance for f and the compact function. - -`separate` can be defined by mapping over `f (Either a b)` and `f (Either b a)`, using `hush` to convert to -an `Optional` and compact to convert to `f a` and `f b`, respectively. - --} - let Either = ./../Either/Type - -in let flipEither = ./../Either/flipEither - -in let hush = ./../Either/hush - -in let compose = (./../Function/category).compose - -in λ(f : Type → Type) - → λ(mapOptional : ∀(a : Type) → ∀(b : Type) → (a → Optional b) → f a → f b) - → { mapOptional = - mapOptional - , mapEither = - λ(a : Type) - → λ(l : Type) - → λ(r : Type) - → λ(k : a → Either l r) - → λ(fa : f a) - → { _1 = - mapOptional - a - l - ( compose - a - (Either r l) - (Optional l) - (hush r l) - (compose a (Either l r) (Either r l) (flipEither l r) k) - ) - fa - , _2 = - mapOptional - a - r - (compose a (Either l r) (Optional r) (hush l r) k) - fa - } - } - : ./Type f diff --git a/Compactable/separate b/Compactable/separate index 83c787a..e59660c 100644 --- a/Compactable/separate +++ b/Compactable/separate @@ -21,14 +21,29 @@ in ./Compactable/mapEither -} let Either = ./../Either/Type +in let compose = (./../Function/category).compose + +in let hush = ./../Either/hush + +in let flipEither = ./../Either/flipEither + in λ(f : Type → Type) → λ(c : ./Type f) → λ(l : Type) → λ(r : Type) → λ(fa : f (Either l r)) - → c.mapEither - (Either l r) - l - r - ((./../Function/category).identity (Either l r)) - fa + → { _1 = + c.mapOptional + (Either l r) + l + ( compose + (Either l r) + (Either r l) + (Optional l) + (hush r l) + (flipEither l r) + ) + fa + , _2 = + c.mapOptional (Either l r) r (hush l r) fa + } diff --git a/Either/compactable b/Either/compactable index 79c514f..0af0aff 100644 --- a/Either/compactable +++ b/Either/compactable @@ -1,5 +1,5 @@ {- -mapEither : (a -> Either l r) -> Either m a -> { _1 : Either m l, _2 : Either m r } +mapOptional : (a -> Optional b) -> Either m a -> Either m b -} let Either = ./Type @@ -7,32 +7,25 @@ in let Monoid = ./../Monoid/Type in λ(m : Type) → λ(monoid : Monoid m) - → ./../Compactable/fromMapEither - (Either m) - ( λ(a : Type) - → λ(l : Type) - → λ(r : Type) - → λ(k : a → Either l r) - → λ(e : Either m a) - → let EL = constructors (Either m l) - - in let ER = constructors (Either m r) - - in merge - { Left = - λ(x : m) → { _1 = EL.Left x, _2 = ER.Left x } - , Right = - λ(x : a) - → merge - { Left = - λ(x : l) - → { _1 = EL.Right x, _2 = ER.Left monoid.unit } - , Right = - λ(y : r) - → { _1 = EL.Left monoid.unit, _2 = ER.Right y } - } - (k x) - } - e - ) + → { mapOptional = + λ(a : Type) + → λ(b : Type) + → λ(k : a → Optional b) + → λ(either : Either m a) + → let E = constructors (Either m b) + + in merge + { Left = + λ(x : m) → E.Left x + , Right = + λ(y : a) + → Optional/fold + b + (k y) + (Either m b) + E.Right + (E.Left monoid.unit) + } + either + } : ./../Compactable/Type (Either m) diff --git a/List/compactable b/List/compactable index 2192494..1f32701 100644 --- a/List/compactable +++ b/List/compactable @@ -1,22 +1,16 @@ - let Either = ./../Either/Type + let Optional/toList = + https://raw.githubusercontent.com/dhall-lang/dhall-lang/0a7f596d03b3ea760a96a8e03935f4baa64274e1/Prelude/Optional/toList -in let compose = (./../Function/category).compose - -in let partition = ./../Either/partition - -in let map = (./functor).map - -in ./../Compactable/fromMapEither - List - ( λ(a : Type) - → λ(l : Type) - → λ(r : Type) - → λ(k : a → Either l r) - → compose - (List a) - (List (Either l r)) - { _1 : List l, _2 : List r } - (partition l r) - (map a (Either l r) k) - ) +in { mapOptional = + λ(a : Type) + → λ(b : Type) + → λ(k : a → Optional b) + → λ(list : List a) + → List/fold + a + list + (List b) + (λ(x : a) → λ(xs : List b) → Optional/toList b (k x) # xs) + ([] : List b) + } : ./../Compactable/Type List diff --git a/Optional/compactable b/Optional/compactable index 04df158..56f1efe 100644 --- a/Optional/compactable +++ b/Optional/compactable @@ -1,11 +1,10 @@ let bind = (./monad).bind -in ./../Compactable/fromMapOptional - Optional - ( λ(a : Type) - → λ(b : Type) - → λ(k : a → Optional b) - → λ(o : Optional a) - → bind a b o k - ) +in { mapOptional = + λ(a : Type) + → λ(b : Type) + → λ(k : a → Optional b) + → λ(o : Optional a) + → bind a b o k + } : ./../Compactable/Type Optional From 74036eb8ca123b17fec90fa1394dc20cdbd53048 Mon Sep 17 00:00:00 2001 From: FintanH Date: Tue, 5 Feb 2019 16:07:48 +0000 Subject: [PATCH 24/25] Update docs and found some type errors --- Compactable/Type | 19 ++++---- Compactable/apEither | 8 +++- Compactable/apOptional | 3 +- Compactable/bindEither | 3 +- Compactable/bindOptional | 3 +- Compactable/compact | 10 ++-- Compactable/mapEither | 59 +++++++++++++++++++++++ Compactable/separate | 38 +++++---------- Compactable/traverseEither | 79 ++++++++++++++++++++++++++++--- Compactable/traverseOptional | 92 ++++++++++++++++++++++++++++++++++++ 10 files changed, 260 insertions(+), 54 deletions(-) create mode 100644 Compactable/mapEither diff --git a/Compactable/Type b/Compactable/Type index 7009fe3..2583b87 100644 --- a/Compactable/Type +++ b/Compactable/Type @@ -1,18 +1,15 @@ {- -Compactable serves as an abstraction over filtering and partitioning, using two functions -compact and separate, respectively. +Compactable serves as an abstraction over filtering using a mapping function to `Optional`s over +a higher-kind `f : Type -> Type`. -Both functions work over some higher kind f (Type -> Type). +`mapOptional` should map over the `f` applying the function `a -> Optional b` and filtering +out `None` values, leaving only the values contained in the `Some` values. -compact works over the f when it is fully applied with an Optional type. It filters out None -values, leaving only the values contained in the Some values. - -separate works over the f when it is fully applied with an Either type. It partitions Left -values to the _1 element of a tuple, and Right values to the _2 element of a tuple. - -Since both functions can be written in terms of the other, we can create instances by choosing one -of the function fromCompact or fromSeparate. +We can see the relation between `mapOptional` and `filter` by observing that we keep values when +we have `Some` i.e. `True` for `filter`, and discard vaues when have `None` i.e. `False` for `filter`. +`mapOptional` is more powerful than `filter` because we can also transform our values to another type `b`, +whereas `filter` will only work on values of type `a`. -} λ(f : Type → Type) diff --git a/Compactable/apEither b/Compactable/apEither index bc65d16..ef6e360 100644 --- a/Compactable/apEither +++ b/Compactable/apEither @@ -1,6 +1,11 @@ {- -apEither maps an `f` of functions to Eithers over the `f a` and `separate`s `Left`s from `Right`s. +When `f` is an Applicative we can apply a function that separates results, via `Either`, within the Applicative +context while still preserving the semantics of `ap`. + +Examples: + +``` let E = constructors (./Either/Type Natural Natural) in ./Compactable/apEither @@ -14,6 +19,7 @@ in ./Compactable/apEither ] [ 0, 1, 2, 3, 4, 5 ] = { _1 = [ 0, 2, 4, 1, 3, 5 ], _2 = [ 1, 3, 5, 0, 2, 4 ] } +``` -} let Applicative = ./../Applicative/Type diff --git a/Compactable/apOptional b/Compactable/apOptional index b9c07d6..d12f3f3 100644 --- a/Compactable/apOptional +++ b/Compactable/apOptional @@ -1,6 +1,7 @@ {- -apOptional maps a `f` of functions to Optionals over the `f` and `compact`s away the `None` values. +When `f` is an Applicative we can apply a function that compacts results, via `Optional`, within the Applicative +context while still preserving the semantics of `ap`. Examples: diff --git a/Compactable/bindEither b/Compactable/bindEither index 19655c4..3801eb1 100644 --- a/Compactable/bindEither +++ b/Compactable/bindEither @@ -1,6 +1,7 @@ {- -bindEither binds to a `f` of Optional over the `f a` and `separate`s `Left`s and `Right`s. +When `f` is a Monad we can bind a function that separates results, via `Either`, within the Monadic +context while still preserving the semantics of `bind`. Examples: diff --git a/Compactable/bindOptional b/Compactable/bindOptional index 310464b..0d853c7 100644 --- a/Compactable/bindOptional +++ b/Compactable/bindOptional @@ -1,6 +1,7 @@ {- -bindOptional binds to a `f` of Optional over the `f a` and `compact`s away the `None` values. +When `f` is a Monad we can apply a function that compacts results, via `Optional`, within the Monadic +context while still preserving the semantics of `bind`. Examples: diff --git a/Compactable/compact b/Compactable/compact index df84f9b..6c8158f 100644 --- a/Compactable/compact +++ b/Compactable/compact @@ -1,18 +1,16 @@ {- -mapOptional maps a function to Optionals over the `f` and `compact`s away the `None` values. +`compact` removes any `None` values from `f` and preserves the `Some` values, compacting +the result. Examples: ``` -./Compactable/mapOptional +./Compactable/compact List ./List/compactable -./List/functor Natural -Natural -(λ(n : Natural) → if Natural/even n then Some n else None Natural) -[ 1, 2, 3, 4, 5 ] +[ None Natural, Some 2, None Natural, Some 4, None Natural ] = [ 2, 4 ] ``` diff --git a/Compactable/mapEither b/Compactable/mapEither new file mode 100644 index 0000000..fc4d3bf --- /dev/null +++ b/Compactable/mapEither @@ -0,0 +1,59 @@ +{- + +Similar to a Functor map over `f` where `b` is constrained to `Either`. This constraint gives +us enough information to partition results into a tuple, where `Left`s match to `_1` and `Right`s +match to `_2`. + +`mapEither` can also be seen as a parititioning function. + +Examples: + +``` + let E = constructors (./Either/Type Natural Natural) + +in ./Compactable/mapEither + List + ./List/compactable + ./List/functor + Natural + Natural + (λ(n : Natural) → if Natural/even n then E.Left n else E.Right n) + [ 1, 2, 3, 4, 5 ] += { _1 = [ 2, 4 ], _2 = [ 1, 3, 5 ] } +``` + +-} + let Either = ./../Either/Type + +in let compose = (./../Function/category).compose + +in let hush = ./../Either/hush + +in let flipEither = ./../Either/flipEither + +in λ(f : Type → Type) + → λ(c : ./Type f) + → λ(a : Type) + → λ(l : Type) + → λ(r : Type) + → λ(k : a → Either l r) + → λ(fa : f a) + → { _1 = + c.mapOptional + a + l + ( compose + a + (Either r l) + (Optional l) + (hush r l) + (compose a (Either l r) (Either r l) (flipEither l r) k) + ) + fa + , _2 = + c.mapOptional + a + r + (compose a (Either l r) (Optional r) (hush l r) k) + fa + } diff --git a/Compactable/separate b/Compactable/separate index e59660c..abc9093 100644 --- a/Compactable/separate +++ b/Compactable/separate @@ -1,49 +1,33 @@ {- -mapEither maps a function to Either over the `f` and `separate`s `Left`s from `Right`s. +`separate` partitions any `Left` values from `f` into the `_1` side of a tuple, and any `Right` values +from `f` into the `_2` side of a tuple, essentially separating the values. Examples: ``` let E = constructors (./Either/Type Natural Natural) -in ./Compactable/mapEither +in ./Compactable/separate List ./List/compactable - ./List/functor Natural Natural - (λ(n : Natural) → if Natural/even n then E.Left n else E.Right n) - [ 1, 2, 3, 4, 5 ] + [ E.Right 1, E.Left 2, E.Right 3, E.Left 4, E.Right 5 ] = { _1 = [ 2, 4 ], _2 = [ 1, 3, 5 ] } ``` -} let Either = ./../Either/Type -in let compose = (./../Function/category).compose - -in let hush = ./../Either/hush - -in let flipEither = ./../Either/flipEither - in λ(f : Type → Type) → λ(c : ./Type f) → λ(l : Type) → λ(r : Type) - → λ(fa : f (Either l r)) - → { _1 = - c.mapOptional - (Either l r) - l - ( compose - (Either l r) - (Either r l) - (Optional l) - (hush r l) - (flipEither l r) - ) - fa - , _2 = - c.mapOptional (Either l r) r (hush l r) fa - } + → ./mapEither + f + c + (Either l r) + l + r + ((./../Function/category).identity (Either l r)) diff --git a/Compactable/traverseEither b/Compactable/traverseEither index e2e118b..d2354b0 100644 --- a/Compactable/traverseEither +++ b/Compactable/traverseEither @@ -1,3 +1,69 @@ +{- + +When `f` is Traverable we can apply a function that separates results, via `Either`, within the Applicative +context while still preserving the semantics of the `traverse`. + +Examples: + +``` + let Either = ./Either/Type + +in let E = constructors (Either Natural Natural) + +in ./Compactable/traverseEither + List + ./List/compactable + ./List/traversable + Optional + ./Optional/applicative + Natural + Natural + Natural + ( λ(x : Natural) + → if Natural/isZero x + + then None (Either Natural Natural) + + else if Natural/odd x + + then Some (E.Left x) + + else Some (E.Right x) + ) + [ 1, 2, 3, 4, 5] += Some { _1 = [ 1, 3, 5 ], _2 = [ 2, 4 ] } +``` + +``` + let Either = ./Either/Type + +in let E = constructors (Either Natural Natural) + +in ./Compactable/traverseEither + List + ./List/compactable + ./List/traversable + Optional + ./Optional/applicative + Natural + Natural + Natural + ( λ(x : Natural) + → if Natural/isZero x + + then None (Either Natural Natural) + + else if Natural/odd x + + then Some (E.Left x) + + else Some (E.Right x) + ) + [ 0, 1, 2, 3, 4, 5] += None { _1 : List Natural, _2 : List Natural } +``` + +-} let Traversable = ./../Traversable/Type in let Applicative = ./../Applicative/Type @@ -10,11 +76,12 @@ in λ(f : Type → Type) → λ(g : Type → Type) → λ(applicative : Applicative g) → λ(a : Type) - → λ(b : Type) - → λ(k : a → g (Either a b)) + → λ(l : Type) + → λ(r : Type) + → λ(k : a → g (Either l r)) → λ(fa : f a) → applicative.map - (f (Either a b)) - { _1 : f a, _2 : f b } - (./separate f c a b) - (traversable.traverse g applicative a (Either a b) k fa) + (f (Either l r)) + { _1 : f l, _2 : f r } + (./separate f c l r) + (traversable.traverse g applicative a (Either l r) k fa) diff --git a/Compactable/traverseOptional b/Compactable/traverseOptional index fcabe08..f6ee0be 100644 --- a/Compactable/traverseOptional +++ b/Compactable/traverseOptional @@ -1,3 +1,95 @@ +{- + +When `f` is Traversable we can apply a function that compacts results, via `Optional`, within the Applicative +context while still preserving the semantics of the `traverse`. + +Examples: + +``` + let Either = ./Either/Type + +in let E = constructors (Either Text (Optional Natural)) + +in ./Compactable/traverseOptional + List + ./List/compactable + ./List/traversable + (Either Text) + (./Either/applicative/sequential Text) + Natural + Natural + ( λ(x : Natural) + → if Natural/isZero x + + then E.Left "No Zeros Allowed!!" + + else if Natural/odd x + + then E.Right (Some x) + + else E.Left "Only Odds!!" + ) + [ 1, 2, 3, 4, 5 ] += < Left = "Only Odds!!" | Right : List Natural > +``` + +``` + let Either = ./Either/Type + +in let E = constructors (Either Text (Optional Natural)) + +in ./Compactable/traverseOptional + List + ./List/compactable + ./List/traversable + (Either Text) + (./Either/applicative/sequential Text) + Natural + Natural + ( λ(x : Natural) + → if Natural/isZero x + + then E.Left "No Zeros Allowed!!" + + else if Natural/odd x + + then E.Right (Some x) + + else E.Left "Only Odds!!" + ) + [ 0, 1, 2, 3, 4, 5 ] += < Left = "No Zeros Allowed!!" | Right : List Natural > +``` + +``` + let Either = ./Either/Type + +in let E = constructors (Either Text (Optional Natural)) + +in ./Compactable/traverseOptional + List + ./List/compactable + ./List/traversable + (Either Text) + (./Either/applicative/sequential Text) + Natural + Natural + ( λ(x : Natural) + → if Natural/isZero x + + then E.Left "No Zeros Allowed!!" + + else if Natural/odd x + + then E.Right (Some x) + + else E.Left "Only Odds!!" + ) + [ 1, 3, 5 ] += < Right = [ 1, 3, 5 ] | Left : Text > +``` + +-} let Traversable = ./../Traversable/Type in let Applicative = ./../Applicative/Type From 7429abcd38dcb569a230a4890ce5b4e590bcf283 Mon Sep 17 00:00:00 2001 From: FintanH Date: Sat, 16 Feb 2019 17:29:14 +0000 Subject: [PATCH 25/25] Move flipEither to flip. Remove not needed doc --- Compactable/mapEither | 4 ++-- Either/compactable | 3 --- Either/{flipEither => flip} | 0 3 files changed, 2 insertions(+), 5 deletions(-) rename Either/{flipEither => flip} (100%) diff --git a/Compactable/mapEither b/Compactable/mapEither index fc4d3bf..52f2152 100644 --- a/Compactable/mapEither +++ b/Compactable/mapEither @@ -29,7 +29,7 @@ in let compose = (./../Function/category).compose in let hush = ./../Either/hush -in let flipEither = ./../Either/flipEither +in let flip = ./../Either/flip in λ(f : Type → Type) → λ(c : ./Type f) @@ -47,7 +47,7 @@ in λ(f : Type → Type) (Either r l) (Optional l) (hush r l) - (compose a (Either l r) (Either r l) (flipEither l r) k) + (compose a (Either l r) (Either r l) (flip l r) k) ) fa , _2 = diff --git a/Either/compactable b/Either/compactable index 0af0aff..e7d8719 100644 --- a/Either/compactable +++ b/Either/compactable @@ -1,6 +1,3 @@ -{- -mapOptional : (a -> Optional b) -> Either m a -> Either m b --} let Either = ./Type in let Monoid = ./../Monoid/Type diff --git a/Either/flipEither b/Either/flip similarity index 100% rename from Either/flipEither rename to Either/flip