monet / monet.js

monet.js - Monadic types library for JavaScript
https://monet.github.io/monet.js/
MIT License
1.6k stars 114 forks source link

New operators #78

Closed ulfryk closed 6 years ago

ulfryk commented 8 years ago

@cwmyers @WojciechP @dumpstate - maybe you guys have any propositions? Also you can share opinions on this draft: https://paper.dropbox.com/doc/MonetJS-API-extension-draft-ByKQgJaXepKka77XzpibA

WojciechP commented 8 years ago

Hello, I haven't used monet since my last contributions, so I'm not really up to date with recent modifications. I do have a few comments, but they are non-technical: rather related to my sense of enhancing/decreasing readability and maintaiability, so by no means hard rules:

For Maybe:

I believe EIther.fold should have signature of (f: A => X, g: B => X) => X for Either<A, B>, so it's a catamorphism. And I advocate against aliases in general, naming things is hard.

ulfryk commented 8 years ago

@WojciechP - nice to see you here :)

Maybe you have a good idea how to name lazy versions of orSome and orElse (without overloading and without breaking backwards compatibility) ?

cwmyers commented 8 years ago

Hi guys,

Thanks for your work again @ulfryk. I have a couple of comments:

I like .forEach but I wonder if it should be on all monads? Does it make sense for the IO monad? I like it for Either, List, NEL and Maybe -- that is the iterable monads. I think the same goes for the other methods.

The Either monad should have fold but I think it is an alias for cata and not bimap.

The other Maybe instances look pretty good too, but just to be clear are you suggesting creating .orElseLazy() method and leaving .orElse as is?

Thanks again for your work!

ulfryk commented 8 years ago

@cwmyers - you are absolutely right about fold - it's not bimap ;)

I suggest adding lazy versions of orSome and orElse. What do you mean by and leaving .orElse as is?

cwmyers commented 8 years ago

I just mean leaving .orElse strict and creating a new method .orElseLazy which is lazy :-) I.e. not changing the current behaviour of orElse.

ulfryk commented 8 years ago

Yes :D

treybrisbane commented 7 years ago

Hey guys, just noticed this issue.

I'm glad to see that Either.fold is already on the list of additions being considered! In fact, the reason I'm here is because I was going to ask about adding a fold alias for all the cata methods (I'd totally be willing to do this work myself). I noticed, however, that Maybe already has a fold method with the signature fold(ifNone: B)(ifSome: A => B): B. This seems to be currently undocumented, so how would you guys feel about changing (or overloading) that to fold(ifNone: () => B, ifSome: A => B): B? Given that you're already looking into adding Either.fold, this would maintain consistency by having Maybe.fold be an alias for Maybe.cata just as Either.fold would be to Either.cata.

Thoughts?

erikschoel commented 7 years ago

hello! great project I would to read the draft but am unable to access it.. would you be so kind? i'm considering an attempt to contribute a continuationMonad to monet - would you consider that worthwhile? or is it already there? (last time i checked is a while ago) thanks, cheers Erik

ulfryk commented 7 years ago

@erikschoel - I've checked DRAFT on few browsers (also in incognito windows) and it's available for public reading…

@cwmyers - WDYT about Continuation Monad ?

ulfryk commented 7 years ago

@tbrisbane - actually I (and few my colleagues) use MonetJS extensively in few projects. And we use .fold(ifNone: B)(ifSome: A=> B): B. On the other hand overloading it is not possible -- consider situation when we have Maybe[A => B] - how would JS know that arg passed to fold is not lazy?

erikschoel commented 7 years ago

well.. for web development I fell sometimes split into halves:

  1. running "stuff" as quickly and smoothly as possible all the time
  2. loading / deferring / await state etc and subsequently the need to integrate the two as smoothly and going as it were unnoticed to the overall scheme... i have tried quite a bit to use a "free monads over channels approach" but I feel only fits point 1. so now I am experimenting an approach with free monads running in the body of continuationMonads - so when they yield because they ran out - but already know there will be more - I want to tie those together using continuationMonads - rather than taking on a channel or listening somewhere - in other words being way too busy when there momentarily is nothing - but equally continue running the free as soon as possible... just thoughts I have no training or educational background in any of this... there is a very very interesting free monad implementation with an amazing example of threads running continuously - but really - interleaved - I still don't like the redundant activity (quite a bit) when there is nothing to do - but when there is they rock - anyway.. tried to locate the repo but cannot - I can send you the code though if you would like that.. ps: i can now read the doc thanks!! erik
erikschoel commented 7 years ago

for example:

// Generate empty actions before executing the given action. // This can be used for simulating long delays between the start of the // execution and the final result. function delayAction(steps, action) { var actions = numberRange(1, steps).map(function() { return noAction(); }); actions.push(action); return doActions(actions); }

kind of a "let's minimize but we can't really stop eventhough that would be fine"