gcanti / fp-ts

Functional programming in TypeScript
https://gcanti.github.io/fp-ts/
MIT License
10.82k stars 502 forks source link

API Surface Guide for Library Authors #1323

Closed waynevanson closed 3 years ago

waynevanson commented 4 years ago

📖 Documentation

I would like to see documentation that tells me which functions are missing.

For example, chain is always visible when using get[Type]M, but most implementations have a pairing flatten function. I would like to have a place where all these variations are listed so I can release libraries with all familiar interfaces.

This primarily for authors that create new modules from existing modules.

If I were to start writing one of these, where would it go, docs/api-styleguide?

raveclassic commented 4 years ago

Well, flatten is a derived function that can be built in the end-project. Also a need for flatten usually indicates that an end-project incorrectly uses map/chain pair. Could you please provide more info about your problem so that we could find a proper solution?

waynevanson commented 4 years ago

Let's create a typeclass for the following interface:

interface ReaderEither<R, E, A> extends Reader<Either<E, A>> { }

The typeclass implements the following:

const readerEither: Monad3<URI> & Bifunctor3<URI> & Alt3<URI> & MonadThrow3<URI> = {
   URI,
   // ... methods from typeclass
}

In our module (this file), we will export the following. These functions are already implemented for typeclass, so we will definitely not forget them.

export const { 
  ap,
  alt,
  bimap,
  chain,
  map,
  mapLeft,
  of,
  throwError,
} = readerEither

But what about all those other handy functions we rely on? They're not implemented and it takes some time to figure out what they do and how they relate to other instances.

For example, the function flatten is basically chain(map) using the pipeables api, which is implemented manuall on all typeclass that implement Monad. When I create a typeclass that is a monad, there's no resource to say "you should include flatten as a helper function"

This is just one function, but what about all the other functions like constructors, destructors, combinators and get[Instance]? It'd be nice to see a list of stuff we should implement, in this case from*, from*K, from*W. These functions inherit from existing modules because our type ReaderEither implement Reader and Either

It may not even be worth the hassle, because if someone is writing an fp-ts library, then they need to know how it all works anyway. Or perhaps wait for version 3 to be release before going on this endeavor. Or perhaps the grind of learning all these API's is what makes fp-ts fun to use?

I'm unclear on a solution, because I'm unclear on the problem.