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

replace Monoid dependency with Alternative dependency for ‘filterM’ #37

Merged
merged 1 commit into from
Mar 29, 2017

Conversation

davidchambers
Copy link
Member

⚠️ This is a breaking change.

It became apparent in sanctuary-js/sanctuary#359 that Z.filterM(odd, Just(4)) is invalid due to the Monoid (m a) constraint. Just(4) cannot satisfy this constraint as it cannot satisfy the requirements of Semigroup. Just(4) can, though, satisfy the requirements of Alternative.

This will allow S.filterM to operate on values of type Maybe a even with type checking enabled.

test/List.js Outdated
@@ -67,6 +69,10 @@ List.prototype[FL.chain] = function(f) {
Z.concat(f(this.head), Z.chain(f, this.tail));
};

List.prototype[FL.alt] = function(other) {
Copy link
Member

@safareli safareli Mar 6, 2017

Choose a reason for hiding this comment

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

In haskell alt for List is concat:

instance Alternative [] where
    empty = []
    (<|>) = (++)

Copy link
Member Author

Choose a reason for hiding this comment

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

Good catch. I find this counter-intuitive, so I tend to forget. Thanks for the reminder. :)

Copy link
Member

Choose a reason for hiding this comment

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

Even though, both of the implementations will conform to Alternative laws

Copy link
Member

@safareli safareli left a comment

Choose a reason for hiding this comment

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

@syaiful6
Copy link

syaiful6 commented Mar 6, 2017

We maybe need to relax the constraint, instead of Alternative, we can just take Plus constraint. List can implements Plus, but it can't implements Alternative, as it violate the distribute laws of Alternative as Fantasy Land defined. Because x.ap(f.alt(g)) is not equivalent to x.ap(f).alt(x.ap(g)) in List.

@safareli
Copy link
Member

safareli commented Mar 6, 2017

@syaiful6 for Arrayx.ap(f.alt(g)) is equivalent to x.ap(f).alt(x.ap(g))

for example:

const x = [1]
const f = [a => a+1]
const g = [a => a*3]
f.alt(g) = [a => a+1, a => a*3]
x.ap(f.alt(g)) = [(a => a+1)(1), (a => a*3)(1)]
x.ap(f.alt(g)) = [2, 3]
x.ap(f) = [2]
x.ap(g) = [3]
x.ap(f).alt(x.ap(g)) = alt([2], [3]) = [2,3] 

i.e. List is valid Alternative when alt is concat

@syaiful6
Copy link

syaiful6 commented Mar 6, 2017

ah, correct..

@davidchambers
Copy link
Member Author

I modified Irakli's example to convince myself that the equivalence is not limited to singleton lists:

> ([(+ 1),(+ 9)] <|> [(* 3),(* 9)]) <*> [1,2,3]
[2,3,4,10,11,12,3,6,9,9,18,27]

> [(+ 1),(+ 9)] <*> [1,2,3] <|> [(* 3),(* 9)] <*> [1,2,3]
[2,3,4,10,11,12,3,6,9,9,18,27]

@davidchambers davidchambers force-pushed the davidchambers/filter branch 3 times, most recently from 5b19a45 to fa4df43 Compare March 15, 2017 15:09
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.

3 participants