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

Missing "join" method on ADTs #388

Open
mrhubbs opened this issue Apr 5, 2019 · 9 comments
Open

Missing "join" method on ADTs #388

mrhubbs opened this issue Apr 5, 2019 · 9 comments

Comments

@mrhubbs
Copy link

mrhubbs commented Apr 5, 2019

Based on my understanding of many of the ADTs, as described here, I think crocks is missing join.

Here is a simplified use case (I realize I could create this function with more of the functional building-blocks Crocks supplies):

// { } -> String -> Either(Error String, a)
const getData = payload => {
  return field => {
    const data = payload[field]

    // hmmm..
    if (!data) {
      return Left(new Error(`Cannot get field "${data}"`))
    } else {
      return Right(data)
    }
  }
}

const result = Either(
  getData({ 10: 100, 'dogs': 'cats' })
)
.ap(Right('dogs'))

console.log(result)
// Right Right 'cats'

The problem is that the result is a Right inside a Right.

I'd like to be able to do this:

const result = Either(
  getData({ 10: 100, 'dogs': 'cats' })
)
.ap(Right('dogs'))
.join()

console.log(result)
// Right 'cats'

Am I missing something? Is there a different way to use ap that wouldn't create nested types?

@evilsoft
Copy link
Owner

evilsoft commented Apr 6, 2019

You are correct that the for something to be an actual Monad is should have a join function, there are a couple issues with that though in JavaScript. Namely it is the fact that Array is a Monad and includes a join method that will takes an Array to a String. That was the driving factor for it not being included in this library. It would be nice to come up with a name for it other then join. Was 🌽sidering flatten, but that creates issues with proposals on Array.

The good news is, the math allows us to derive this function by simply chaining an identity function as so:

import chain from 'crocks/pointfree/chain'
import identity from 'crocks/combinators/identity'

// joinM :: Monad m => m(m a) -> m a
const joinM =
  chain(identity)

We are totally open to suggestions for how this function should be names, so if possible we would like to keep this issue open to gather suggesions. Would this joinM be helpful enough for you in the mean time while we get this naming sorted?

@mrhubbs
Copy link
Author

mrhubbs commented Apr 9, 2019

Hi @evilsoft. Yes, that joinM will be very helpful to me. Thanks a lot!

Here are some random - probably not mathematically sound - brainstorm ideas:

  • unbox
  • unNest
  • unlade
  • uncrate
  • merge
  • meld
  • smoosh
  • squash
  • fuse
  • melt

On a different note, I wanted to say earlier that I'm really enjoying this library. I tried a few other functional libraries after reading this book and they felt rather abstruse. Things are really clicking for me with crocks. Thanks a lot!

@evilsoft
Copy link
Owner

I am a fan of fuse btw.

@karthikiyengar
Copy link
Collaborator

I have strong memories of missing this function, and this looks useful for sure. Since we're prefixing m to most array-colliding functions like mconcat, mreduce et al, we could even consider mjoin for consistency's sake? I can chalk this out if we're in agreement.

@mrhubbs
Copy link
Author

mrhubbs commented Jul 22, 2019

I think following the established convention is a good idea, but I don’t think I have enough familiarity with the codebase to give a strong opinion.

@dalefrancis88
Copy link
Collaborator

well @mrhubbs this is a pretty good first issue to complete if you'd like to try your hand at contributing to the codebase. @karthikiyengar looks keen to help

@dalefrancis88
Copy link
Collaborator

@karthikiyengar the m is because it's performing that action within the context of the given monoid. Not so much that it collides with the array functions

@mrhubbs
Copy link
Author

mrhubbs commented Jul 25, 2019

@dalefrancis88 I'd love to, thanks for the invitation. However I'm pretty busy the next few weeks. Perhaps it'd be best for @karthikiyengar to take care of it? Does this have a particular timeframe?

@dalefrancis88
Copy link
Collaborator

Nope, it's first in best dressed really, and you're the first to ask for it. If Karth gets in there before you then it's all good, there are other things that need to be added :)

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

No branches or pull requests

4 participants