Fp-ts: Combining two Eithers

Created on 28 Oct 2018  路  12Comments  路  Source: gcanti/fp-ts

Hello, first sorry for not using the template.
This is a question and not a feature request or bug report, I couldn't find a better place to ask this, do you have a slack channel or something like that?

Also thank you for this awesome library 鉂わ笍

I needed a function to combine two Eithers, so I wrote the following one

const combine = <L, R1, R2>(a: Either<L, R1>, b: Either<L, R2>): Either<L, [R1, R2]> => {
  if (a.isLeft()) {
    return left(a.value)
  }

  if (b.isLeft()) {
    return left(b.value)
  }

  return right<L, [R1, R2]>([a.value, b.value])
}

Do something like that exists in this library?

Most helpful comment

The subject is "Applicative functors", there are many resources about them.

A couple of links from the top of my head

All 12 comments

I think you can use sequenceT:

import { sequenceT } from 'fp-ts/lib/Apply';
import { either } from 'fp-ts/lib/Either';

declare const a: Either<string, number>
declare const b: Either<string, string>

sequenceT(either)(a, b) // Either<string, [number, string]>

@giogonzo OMG I'm astonished, that's nuts.
Can you point to me where I can learn more about these things?
You solved my issue, but I would like to know if we have something like an slack channel where I could ask those things before I close it.

I'm not sure either 馃槄
I think https://functionalprogramming.slack.com / #typescript channel could be a good place (and @gcanti is answering there 馃槈). Otherwise stackoverflow?

Nice, thank you.

@giogonzo How can I join the workspace? It seems I need an inventation?

@mlegenhausen sorry wrong link, this should be the correct one: https://fpchat-invite.herokuapp.com/

Adding a few more thoughts to this discussion re learning and questions/answers: I do think slack could be a cheap solution for quick Q&A, but at the same time I think it's a shame that it typically results on a lot of content that is quickly "lost": not easily indexable/searchable, free slack communities also have a limit in visible messages so after some time they just disappear.

I often find myself searching for specific terms among this repo's issues and most of the time my question (or a very similar one) has already been answered in the past, and it remains available here.

Not sure if you guys have other suggestions, or maybe @gcanti has some guidance on these topics

I do think slack could be a cheap solution for quick Q&A, but at the same time I think it's a shame that it typically results on a lot of content that is quickly "lost"

I agree.

Also it's fine for me if people want to use issues for questions, as long as they are not trivial.

IMO there's been plenty of interesting discussions so far.

@giogonzo @gcanti Can you share the thought process behind this? What is the theory behind all of this goodness? Can you provide the resources for mere mortal to learn more about this?

@livingmine the theory behind is related to Applicative functors. If F admits an istance of Apply then you can lift any function

const f = (a: A) => (b: B) => ... => R

to a function

const liftedf = (fa: F<A>) => (fb: F<B>) => ... F<R>

Example with f = tuple2, f = tuple3, etc...

import { Apply1 } from 'fp-ts/lib/Apply'
import { URIS, Type } from 'fp-ts/lib/HKT'

const liftedtuple2 = <F extends URIS>(F: Apply1<F>) => {
  return <A>(fa: Type<F, A>) => <B>(fb: Type<F, B>): Type<F, [A, B]> =>
    F.ap(F.map(fa, (a: A) => (b: B): [A, B] => [a, b]), fb)
}

const liftedtuple3 = <F extends URIS>(F: Apply1<F>) => {
  return <A>(fa: Type<F, A>) => <B>(fb: Type<F, B>) => <C>(fc: Type<F, C>): Type<F, [A, B, C]> =>
    F.ap(F.ap(F.map(fa, (a: A) => (b: B) => (c: C): [A, B, C] => [a, b, c]), fb), fc)
}

// etc...

sequenceT (where the T means "tuple") is just an application of this pattern

const sequenceT2 = <F extends URIS>(F: Apply1<F>) => <A, B>(fa: Type<F, A>, fb: Type<F, B>): Type<F, [A, B]> => {
  return liftedtuple2(F)(fa)(fb)
}

const sequenceT3 = <F extends URIS>(F: Apply1<F>) => <A, B, C>(
  fa: Type<F, A>,
  fb: Type<F, B>,
  fc: Type<F, C>
): Type<F, [A, B, C]> => {
  return liftedtuple3(F)(fa)(fb)(fc)
}

// etc...

Now for a concrete example let's pick option as the Apply instance

import { option, none, some } from 'fp-ts/lib/Option'

console.log(sequenceT2(option)(some(1), some(2))) // => some([1, 2])
console.log(sequenceT2(option)(some(1), none)) // none
console.log(sequenceT3(option)(some(1), some(2), some(3))) // some([1, 2, 3])

@gcanti So what do you call all of these concepts? There has to be a subject for these, and what is the best way to learn it? Are there any good resources you can point me to?

The subject is "Applicative functors", there are many resources about them.

A couple of links from the top of my head

Was this page helpful?
0 / 5 - 0 ratings

Related issues

FruitieX picture FruitieX  路  3Comments

gcanti picture gcanti  路  3Comments

mohsensaremi picture mohsensaremi  路  3Comments

bobaaaaa picture bobaaaaa  路  4Comments

FredericLatour picture FredericLatour  路  3Comments