gcanti / fp-ts

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

Fluent API Implementation #1196

Open erikjara opened 4 years ago

erikjara commented 4 years ago

🚀 Feature request

Current Behavior

When you use any Monad like Option, Either, etc. You need to use pipe to mutate the wrapped result itself, for example:

import { fromNullable, getOrElse } from 'fp-ts/lib/Option'
import { pipe } from 'fp-ts/lib/pipeable'

const maybeString = fromNullable(null)
const stringResult = pipe(maybeString,
  map(value => `${value}!`),
  getOrElse(() => 'Empty string')
)

console.log(stringResult)

Desired Behavior

I saw in another languajes like Java or something else where they use an Fluent Interface for those chain operations:

Optional<String> maybeString = Optional.ofNullable(null);

return maybeString
  .map(value -> String.format("%s!", value))
  .getOrElse("Empty string");

also jQuery takes a place in Fluent API implementation:

$('<div></div>')
     .html("Fluent API are cool!")
     .addClass("header")
     .appendTo("body")

Then a desired behavior could be something like this:

import { Option } from 'fp-ts/lib/Option'

const maybeString = Option.fromNullable(null)
const stringResult = maybeString
     .map(value => `${value}!`)
     .getOrElse('Empty string')

console.log(stringResult)

Suggested Solution

Use the Polyformic this in Typescript in the Monads Interfaces.

Who does this impact? Who is this for?

Impact all users

Describe alternatives you've considered

I can't get another alternative right now

Additional context

Your environment

Software Version(s)
fp-ts latest
TypeScript latest
DenisFrezzato commented 4 years ago

@erikjara fp-ts@1 had class encoding and fluent API. In this issue you can check out what were the reasons that leaded to the actual encoding.

EDIT: I'm a fp-ts user since when the fluent API was still around. I don't miss it at all. Composing functions with pipe and flow is more powerful. We can create any function and compose them along with the ones from the library. With the fluent API you either have to create a function ("breaking" the fluent flow) or create a new data type extending the one from the library adding the method you're interested in.

newswim commented 4 years ago

@erikjara consider using 1.19, if you prefer the fluent api.

yarn add fp-ts@1.19.5

Also, the pipe function was back-ported, so you'll have access to either style.