Skip to content
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

Merged
merged 5 commits into from
Mar 7, 2019
Merged

Add more morphisms #146

merged 5 commits into from
Mar 7, 2019

Conversation

stevemao
Copy link
Contributor

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!

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!
@i-am-tom
Copy link

Oh no :O what was my mistake?

list
)

suffixes([1, 2, 3, 4, 5]) // [[2, 3, 4, 5], [3, 4, 5], [4, 5], [5], []]
Copy link
Contributor Author

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 😺

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah 😳 Good catch!

Copy link

@i-am-tom i-am-tom left a 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:

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.

Copy link
Contributor Author

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) => {

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

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".

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?

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.

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.

Copy link
Contributor Author

@stevemao stevemao Apr 15, 2017

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.
Copy link
Contributor

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))
Copy link
Contributor

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.
Copy link
Contributor

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

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@char0n A link?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator

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

Copy link
Contributor

@char0n char0n May 20, 2017

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

@jethrolarson
Copy link
Collaborator

Trailing spaces are meaningful in markdown so you shouldn't be stripping them automatically

@stevemao
Copy link
Contributor Author

@jethrolarson not with one space. Two spaces would create a \n but there are two newlines after it so it creates a seperate node already.

@mrtnbroder
Copy link

Whats up with this whole project? so many PRs and issues, can we get this merged in?

@hemanth
Copy link
Owner

hemanth commented Sep 28, 2017

@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.

@stevemao
Copy link
Contributor Author

stevemao commented Mar 7, 2019

@hemanth Sorry for the delay. Conflicts should be resolved

@hemanth
Copy link
Owner

hemanth commented Mar 7, 2019

NP!

Awesomeness after ~2years this PR is going!

@hemanth hemanth merged commit 77f9117 into hemanth:master Mar 7, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants