From f48450d3e7b702ebef1fe81b99c0a197576e9b4e Mon Sep 17 00:00:00 2001 From: Kailuo Wang Date: Tue, 25 Apr 2017 12:23:19 -0400 Subject: [PATCH 1/5] added some category theory into FunctionK document --- docs/src/main/tut/datatypes/functionk.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/docs/src/main/tut/datatypes/functionk.md b/docs/src/main/tut/datatypes/functionk.md index f2fe719c8a..9522b733bc 100644 --- a/docs/src/main/tut/datatypes/functionk.md +++ b/docs/src/main/tut/datatypes/functionk.md @@ -121,3 +121,25 @@ type ErrorOr[A] = Either[String, A] val errorOrFirst: FunctionK[List, ErrorOr] = λ[FunctionK[List, ErrorOr]](_.headOption.toRight("ERROR: the list was empty!")) ``` + +## Natural Transformer + +In category theory, a [natural transformer](https://en.wikipedia.org/wiki/Natural_transformation) provides a morphism between Functors while preserving the internal structures. It's one of the most fundamental notions of category theory. + +If we have two `Functor`s: `F` and `G`, then, being parametric polymorphic, `FunctionK[F, G]` is automatically a natural transformer between them. That is, if we have a `fk: F ~> G`, then for any combination of `A`, `B` and function `f: A => B`, the following two functions are equivalent: +```Scala +(fa:F[A]) => fK(F.map(fa)(f)) +``` +and +```Scala +(fa: F[A]) => G.map(fK(fa))(f) +```` + +We don't need to write a law to test the implementation of the `fk` for the above to be true. It's automatically given by its parametric polymorphism. + +This is why a parametric polymorphic function `FunctionK[F, G]` is sometime referred as a natural transformer. +However, they are two different concepts. `FunctionK` is a stronger and stricter construction than natural transformer. + +For more details, Bartosz Milewski has written a great blog post titled +["Parametricity: Money for Nothing and Theorems for Free"](https://bartoszmilewski.com/2014/09/22/parametricity-money-for-nothing-and-theorems-for-free/). + From 64ac09cbad0f629025602b435e4cf1ae884c10ec Mon Sep 17 00:00:00 2001 From: Kailuo Wang Date: Tue, 25 Apr 2017 12:36:55 -0400 Subject: [PATCH 2/5] correct name --- docs/src/main/tut/datatypes/functionk.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/src/main/tut/datatypes/functionk.md b/docs/src/main/tut/datatypes/functionk.md index 9522b733bc..f7001360ec 100644 --- a/docs/src/main/tut/datatypes/functionk.md +++ b/docs/src/main/tut/datatypes/functionk.md @@ -122,11 +122,11 @@ val errorOrFirst: FunctionK[List, ErrorOr] = λ[FunctionK[List, ErrorOr]](_.headOption.toRight("ERROR: the list was empty!")) ``` -## Natural Transformer +## Natural Transformation -In category theory, a [natural transformer](https://en.wikipedia.org/wiki/Natural_transformation) provides a morphism between Functors while preserving the internal structures. It's one of the most fundamental notions of category theory. +In category theory, a [Natural Transformation](https://en.wikipedia.org/wiki/Natural_transformation) provides a morphism between Functors while preserving the internal structures. It's one of the most fundamental notions of category theory. -If we have two `Functor`s: `F` and `G`, then, being parametric polymorphic, `FunctionK[F, G]` is automatically a natural transformer between them. That is, if we have a `fk: F ~> G`, then for any combination of `A`, `B` and function `f: A => B`, the following two functions are equivalent: +If we have two `Functor`s: `F` and `G`, then, being parametric polymorphic, `FunctionK[F, G]` is automatically a Natural Transformation between them. That is, if we have a `fk: F ~> G`, then for any combination of `A`, `B` and function `f: A => B`, the following two functions are equivalent: ```Scala (fa:F[A]) => fK(F.map(fa)(f)) ``` @@ -137,8 +137,8 @@ and We don't need to write a law to test the implementation of the `fk` for the above to be true. It's automatically given by its parametric polymorphism. -This is why a parametric polymorphic function `FunctionK[F, G]` is sometime referred as a natural transformer. -However, they are two different concepts. `FunctionK` is a stronger and stricter construction than natural transformer. +This is why a parametric polymorphic function `FunctionK[F, G]` is sometime referred as a Natural Transformation. +However, they are two different concepts. `FunctionK` is a stronger and stricter construction than Natural Transformation. For more details, Bartosz Milewski has written a great blog post titled ["Parametricity: Money for Nothing and Theorems for Free"](https://bartoszmilewski.com/2014/09/22/parametricity-money-for-nothing-and-theorems-for-free/). From 1a4a36cee9f467e04781137467c7924ee5749ff8 Mon Sep 17 00:00:00 2001 From: "Kai(luo) Wang" Date: Tue, 25 Apr 2017 15:54:54 -0400 Subject: [PATCH 3/5] feedback --- docs/src/main/tut/datatypes/functionk.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/src/main/tut/datatypes/functionk.md b/docs/src/main/tut/datatypes/functionk.md index f7001360ec..ccfa63bef6 100644 --- a/docs/src/main/tut/datatypes/functionk.md +++ b/docs/src/main/tut/datatypes/functionk.md @@ -124,7 +124,7 @@ val errorOrFirst: FunctionK[List, ErrorOr] = ## Natural Transformation -In category theory, a [Natural Transformation](https://en.wikipedia.org/wiki/Natural_transformation) provides a morphism between Functors while preserving the internal structures. It's one of the most fundamental notions of category theory. +In category theory, a [Natural Transformation](https://en.wikipedia.org/wiki/Natural_transformation) provides a morphism between Functors while preserving the internal structure. It's one of the most fundamental notions of category theory. If we have two `Functor`s: `F` and `G`, then, being parametric polymorphic, `FunctionK[F, G]` is automatically a Natural Transformation between them. That is, if we have a `fk: F ~> G`, then for any combination of `A`, `B` and function `f: A => B`, the following two functions are equivalent: ```Scala @@ -132,13 +132,12 @@ If we have two `Functor`s: `F` and `G`, then, being parametric polymorphic, `Fun ``` and ```Scala -(fa: F[A]) => G.map(fK(fa))(f) +(fa: F[A]) => G.map(fk(fa))(f) ```` We don't need to write a law to test the implementation of the `fk` for the above to be true. It's automatically given by its parametric polymorphism. -This is why a parametric polymorphic function `FunctionK[F, G]` is sometime referred as a Natural Transformation. -However, they are two different concepts. `FunctionK` is a stronger and stricter construction than Natural Transformation. +This is why a parametric polymorphic function `FunctionK[F, G]` is sometimes referred as a Natural Transformation. However, they are two different concepts. For more details, Bartosz Milewski has written a great blog post titled ["Parametricity: Money for Nothing and Theorems for Free"](https://bartoszmilewski.com/2014/09/22/parametricity-money-for-nothing-and-theorems-for-free/). From c82574066f3018c5bcb19a708d2ae89359558b70 Mon Sep 17 00:00:00 2001 From: "Kai(luo) Wang" Date: Fri, 12 May 2017 12:09:33 -0400 Subject: [PATCH 4/5] Update functionk.md --- docs/src/main/tut/datatypes/functionk.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/main/tut/datatypes/functionk.md b/docs/src/main/tut/datatypes/functionk.md index ccfa63bef6..a36a597a65 100644 --- a/docs/src/main/tut/datatypes/functionk.md +++ b/docs/src/main/tut/datatypes/functionk.md @@ -128,7 +128,7 @@ In category theory, a [Natural Transformation](https://en.wikipedia.org/wiki/Nat If we have two `Functor`s: `F` and `G`, then, being parametric polymorphic, `FunctionK[F, G]` is automatically a Natural Transformation between them. That is, if we have a `fk: F ~> G`, then for any combination of `A`, `B` and function `f: A => B`, the following two functions are equivalent: ```Scala -(fa:F[A]) => fK(F.map(fa)(f)) +(fa:F[A]) => fk(F.map(fa)(f)) ``` and ```Scala From 78ded9d12904e7c38af6c708d5a28bc0aeb981f6 Mon Sep 17 00:00:00 2001 From: "Kai(luo) Wang" Date: Mon, 15 May 2017 14:14:34 -0400 Subject: [PATCH 5/5] address feedback --- docs/src/main/tut/datatypes/functionk.md | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/docs/src/main/tut/datatypes/functionk.md b/docs/src/main/tut/datatypes/functionk.md index a36a597a65..53e1cb1070 100644 --- a/docs/src/main/tut/datatypes/functionk.md +++ b/docs/src/main/tut/datatypes/functionk.md @@ -124,20 +124,16 @@ val errorOrFirst: FunctionK[List, ErrorOr] = ## Natural Transformation -In category theory, a [Natural Transformation](https://en.wikipedia.org/wiki/Natural_transformation) provides a morphism between Functors while preserving the internal structure. It's one of the most fundamental notions of category theory. +In category theory, a [natural transformation](https://ncatlab.org/nlab/show/natural+transformation) provides a morphism between Functors while preserving the internal structure. It's one of the most fundamental notions of category theory. -If we have two `Functor`s: `F` and `G`, then, being parametric polymorphic, `FunctionK[F, G]` is automatically a Natural Transformation between them. That is, if we have a `fk: F ~> G`, then for any combination of `A`, `B` and function `f: A => B`, the following two functions are equivalent: +If we have two Functors `F` and `G`, `FunctionK[F, G]` is a natural transformation via parametricity. That is, given `fk: FunctionK[F, G]`, for all functions `A => B` and all `fa: F[A]` the following are equivalent: ```Scala -(fa:F[A]) => fk(F.map(fa)(f)) +fk(F.map(fa)(f)) <-> G.map(fk(fa))(f) ``` -and -```Scala -(fa: F[A]) => G.map(fk(fa))(f) -```` -We don't need to write a law to test the implementation of the `fk` for the above to be true. It's automatically given by its parametric polymorphism. +We don't need to write a law to test the implementation of the `fk` for the above to be true. It's automatically given by parametricity. -This is why a parametric polymorphic function `FunctionK[F, G]` is sometimes referred as a Natural Transformation. However, they are two different concepts. +Thus natural transformation can be implemented in terms of `FunctionK`. This is why a parametric polymorphic function `FunctionK[F, G]` is sometimes referred as a natural transformation. However, they are two different concepts that are not isomorphic. For more details, Bartosz Milewski has written a great blog post titled ["Parametricity: Money for Nothing and Theorems for Free"](https://bartoszmilewski.com/2014/09/22/parametricity-money-for-nothing-and-theorems-for-free/).