-
-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add more morphisms #146
Add more morphisms #146
Conversation
I was watching @DrBoolean's [A Million Ways to Fold in JS](https://www.youtube.com/watch?v=JZSoPZUoR58) but I couldn't understand most of the morphism jargons. I presume the video is for experienced devs who are from a FP language background. The moment when I tried to search for "Catamorphism javascript" on google I couldn't get anything. I really hope there would be more in depth FP resources written in JavaScript. Luckily @i-am-tom kindly wrote up something that could be understood by JS devs like me. I have fixed a minor mistake in @i-am-tom's [original write up](DrBoolean/RecursionTalk#2 (comment)) and tweaked a few wording. Also cc @joneshf @getify @shineli1984 Thanks!
Oh no :O what was my mistake? |
list | ||
) | ||
|
||
suffixes([1, 2, 3, 4, 5]) // [[2, 3, 4, 5], [3, 4, 5], [4, 5], [5], []] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@i-am-tom There should be an empty array as the last element 😺
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yeah 😳 Good catch!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yaaay :D
readme.md
Outdated
|
||
### Paramorphism | ||
|
||
Enhancement of catamorphism. It's like `reduceRight`. However, there's a difference: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd be cautious around the word "enhancement"; for most cases, para
wouldn't be an enhancement - just unnecessary bloat. Kinda similar to how Monad
, in a lot of cases, definitely isn't an enhancement to Functor
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, "enhancement" is not the right word. More like "extension". Looking at Monad
in the docs it doesn't mention the relationship with Functor
so I'll follow the same way.
An `unfold` function. An `unfold` is the opposite of `fold` (`reduce`). It generates a list from a single value. | ||
|
||
```js | ||
const unfold = (f, seed) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I stole this code from @DrBoolean, so I'd probably give him a shout-out.
readme.md
Outdated
// Obviously not safe for lists containing `undefined`, | ||
// but good enough to make the point. | ||
const para = (reducer, accumulator, [x, ... xs]) => | ||
x !== undefined |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably best to update this to match the better example I posted. undefined
is kinda confusing :(
readme.md
Outdated
|
||
A `reduceRight` function. Take a bunch of things, and combine them into another. The morphism is from "bunch of things" to "another". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@stevemao By just looking at this line, I don't have the context as in how 'generalised' we want to be in this repo, but Catamorphism
can be for other ADTs and not just list. List certainly provides good intuition, but should we mention bunch of things
could be just one thing here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quite right. In the most general case, it applies to any Foldable
structure. bunch of things
could indeed be thing
or even no things
!
…f `reduce` doesn't seem to be right either. Changed both to mdn's definition.
|
||
A `reduceRight` function that applies a function against an accumulator and each value of the array (from right-to-left) to reduce it to a single value. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
each value of the array
What I meant here was that it doesn't need to be an array
and
against an accumulator
it doesn't need to be an accumulator
It can be a Maybe Int
. The catamorphism can help to "break" it down into just Int
, so that the Maybe
structure is not preserved.
reduce it to a single value
It may not be a single value. You can re-implement map
using reduce
for list:
const map = reduce((acc, cur) => concat(acc, [cur]))
So I think maybe another example not using list will be better here? just to illustrate that Catamorphism is more general than a fold for a list.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hemanth thoughts?
@@ -727,7 +811,7 @@ An object that has a `concat` function that combines it with another object of t | |||
|
|||
## Foldable | |||
|
|||
An object that has a `reduce` function that can transform that object into some other type. | |||
An object that has a `reduce` function that applies a function against an accumulator and each element in the array (from left to right) to reduce it to a single value. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps the detail about left to right can be omitted as there is also right to left reduce?
In maths, the right to left is actually more common as it is how the functions compose.
A homomorphism is just a structure preserving map. In fact, a functor is just a homomorphism between categories as it preserves the original category's structure under the mapping. | ||
|
||
```js | ||
A.of(f).ap(A.of(x)) == A.of(f(x)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps also give simpler examples such as x => x*2
preserving the addition structure?
|
||
### Catamorphism | ||
|
||
A `reduceRight` function that applies a function against an accumulator and each value of the array (from right-to-left) to reduce it to a single value. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi,
Maybe more simpler and polymorphic explanation presented by Tom Harding.
catamorphism: a way of folding a type up into a value
anamorphism: a way of unfolding a type from a single value
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@char0n A link?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this idea. Catamorphisms are more general than just a reduce and don't always require an accumulator
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jethrolarson exactly; catamorphism can be seen on multiple monadic types with or without Foldable spec
Identity.of(1).get(); //=> catamorphism
Identity.of(1).fold((acc, val) => acc + val, 1); //=> catamorphism
Maybe.fromNull(value).cata(identity, identity); //=> catamorphism
Trailing spaces are meaningful in markdown so you shouldn't be stripping them automatically |
@jethrolarson not with one space. Two spaces would create a |
Whats up with this whole project? so many PRs and issues, can we get this merged in? |
@mrtnbroder This is pretty much active, there are many reasons for open PRs and issues if you go through them. @stevemao it needs a rebase. |
@hemanth Sorry for the delay. Conflicts should be resolved |
NP! Awesomeness after ~2years this PR is going! |
I was watching @DrBoolean's A Million Ways to Fold in JS but I couldn't understand most of the morphism jargons. I presume the video is for experienced devs who are from a FP language background. The moment when I tried to search for "Catamorphism javascript" on google I couldn't get anything. I really hope there would be more in depth FP resources written in JavaScript. Luckily @i-am-tom kindly wrote up something that could be understood by JS devs like me. I have fixed a minor mistake in @i-am-tom's original write up and tweaked a few wording.
Also cc @joneshf @getify @shineli1984
Thanks!