import * as A from 'fp-ts/lib/Array'
import * as E from 'fp-ts/lib/Either'
import { pipe } from 'fp-ts/lib/pipeable'
pipe(
[E.right(1), E.right(2), E.right(3)],
A.sequence(E.either), // <= mega instance
E.bimap(
() => 'error',
() => 'ok'
)
)
The E.either "mega instance" is pretty bad from a tree-shakeablity point of view.
I propose to split this kind of mega instances into specialized ones. For example:
applyEither: Apply2<'Either'> instance for use with sequenceS / sequenceTapplicativeEither: Applicative2<'Either'> instance for use with sequence / TraversemonadEither: Monad2<'Either'> instance, etc...[email protected] users
Oooops... Somehow this slipped my mind sorry.
Yeah, in the linked thread I mean't the type name, so that the instanced would be: instanceFunctor, instanceApply. And since pretty much all users of fp-ts don't import directly from modules but use either import * as O from 'fp-ts/lib/Option' or import { option } from 'fp-ts' (me), then we already have the type's name: O.instanceFunctor or option.instanceFunctor.
@raveclassic instanceFunctor doesn't seems an improvement over functorOption with respect to verbosity but makes more difficult to import the instances automatically in VS Code, I'm leaning towards the current naming convention.
@gcanti I'm ok with the made changes (just splitting the instances to functorOption etc.)
more difficult to import the instances automatically in VS Code
I'm not sure it's good to have import * as O from 'fp-ts/lib/Option' (written by hand) or import { option } from 'fp-ts' (autoimported) together with additional import { functorOption } from 'fp-ts/lib/Option (even autoimported) because we already have the instance in O.functorOption or more weird option.functorOption. But that's just my opinion, again I'm ok with the duplication.
instanceFunctordoesn't seems an improvement overfunctorOptionwith respect to verbosity
@raveclassic (again with respect to verbosity) what about simply "functor"? functorOption or functorTask is not that bad, but applicativeNonEmptyArray is quite verbose. Also option.functor is less weird than option.functorOption.
Do you suggest to drop instance part? like export const functor: Functor1<URI> ... for fp-ts/lib/Option?
I though about it but this may conflict with top-level functions which have the same name as a typeclass, like alt. alt is both an instance of Alt and a top-level function. That's why it's better to add instance: export const instanceAlt and export const alt
So that applicativeNonEmptyArray could be replaced with a shorter instanceApplicative.
Or instanceApplicative for a StateReaderTaskEitherWhatever :D
Also it would mimic purescript/haskell with their instance keyword..
My initial thought was to suggest the typeclass name. Is the option I like the most. But
this may conflict with top-level functions which have the same name as a typeclass, like
alt
If there's an easy way to get around that maybe it is possible to stick with the typeclass name.
Also it would mimic purescript/haskell with their instance keyword..
@raveclassic the current naming convention is stolen from PureScript :) (functorMaybe, applyMaybe, applicativeMaybe, etc...)
Every now and then I even dream of writing a PureScript backend which outputs fp-ts-compatible code :)
If there's an easy way to get around that maybe it is possible to stick with the typeclass name
@gillchristian the easy (but kind of ugly) way is to derogate from the naming convention I guess, so for Option you have
functorapplicativemonadaltInstance (or altI)alternativeWell, altInstance looks good to me :)
So to sum up (sorry for being pedantic but there's some work involved if I must rename all the instances so I want to be sure this time) do you agree to:
functorOption becomes just functoralt at the moment) remove the data type name and add an Instance suffix, e.g. altOption becomes altInstance?
:+1: I agree
:-1: I disagree
when there's a name clash
This would lead to naming not being consistent with each others.
altInstance(oraltI)
What about the I suffix (so functorI, monadI, altI...), so all instances are named following the same convention, without being verbose? Or would having the nth single character suffix be confusing?
I'm personally fine with the tradeoff of only adding it on the ones that have collisions.
But if we go to the route of adding a suffix, the single letter I seems fine. There are already other cases of a single letter suffix (eg. sequenceS & sequenceT)
What about the
Isuffix (sofunctorI,monadI,altI...), so all instances are named following the same convention, without being verbose? Or would having the nth single character suffix be confusing?
We have been importing fp-ts with this convention before we enabled tree-shaking:
import { map as mapO } from "fp-ts/lib/Option";
However with tree-shaking enabled the compiled output is equivalent to the following which is a pattern I prefer.
import * as O from "fp-ts/es6/Option";
In either case, none of the other functions used every day, map, fold, etc are name spaced within fp-ts. Why should the applicative, apply, etc. be name spaced?
I would be in favor of O.apply or even O.Apply to avoid name collisions over applyOption or applyI
I'm for the
rename by removing the data type name
But just 2 cents here: if we add the instance prefix (e.g. instanceFunctor, instanceApply), it provides better discoverability in the IDE - when you type O.ins...... (or option.ins......) the IDE suggests all available instances of the module. I can't think of a real use case where this could be useful but still it could be useful for somebody who is not familiar with fp-ts enough. Again, just 2 cents.
or even
O.Apply
@jleider this is a good idea, upper-case instances (e.g. O.Functor, O.Applicative, O.Alt):
O. they show up as first entries)I like it.
@gcanti that's quite weird in respect to the convention of using leading capital letter only in type names. Also it conflicts with hkt-versions of typeclasses like Applicative<F>
I second upper case names for Haskell typeclass equivalents, and lower case names for functions that take those as inputs.
Most helpful comment
@jleider this is a good idea, upper-case instances (e.g.
O.Functor,O.Applicative,O.Alt):O.they show up as first entries)I like it.