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

Question about Option's Foldable / reduce implementation #495

Closed
babakness opened this issue Jun 25, 2018 · 11 comments
Closed

Question about Option's Foldable / reduce implementation #495

babakness opened this issue Jun 25, 2018 · 11 comments
Labels

Comments

@babakness
Copy link
Contributor

Hello, great library! Just a brief question:

I've noticed that Option's foldable

reduce<B>(b: B, f: (b: B, a: A) => B): B {

is in the opposite order of FantasyLand Foldable

https://github.com/fantasyland/fantasy-land#foldable

u.reduce(f, x)

I'm might be totally misunderstanding that.

@gcanti
Copy link
Owner

gcanti commented Jun 25, 2018

Type inference goes from left to right, so this signature helps typing the reducer

some('foo').reduce(0, (b, a) => ) // b is inferred as number, a as string

@babakness
Copy link
Contributor Author

babakness commented Jun 25, 2018

I tried this with Typescript 2.9

function test<A>( x: (a) => A, y: A ): A {
  return y
}

test( _ => 'a' ,1 )

I get the error

Type 'string' is not assignable to type '1'.

Also with currying

function test<A>( x: (a) => A ): (y:A) => A {
  return (y: A) => y
}
test( _ => 'a')( 1 )

I get the error

Argument of type '1' is not assignable to parameter of type 'string'.

@sledorze
Copy link
Collaborator

@babakness these errors are legit.
What are you trying to demonstrate?

@babakness
Copy link
Contributor Author

babakness commented Jun 25, 2018

@sledorze Well, my original comment:

I've noticed that Option's foldable

reduce<B>(b: B, f: (b: B, a: A) => B): B {

is in the opposite order of FantasyLand Foldable

https://github.com/fantasyland/fantasy-land#foldable

u.reduce(f, x)

I wanted to know why not comply with the fantasy-land reduce. I believe that @gcanti meant that the reverse order is because of typing inference. However, with the orders per fantasy-land (if I understand it correctly), type inference still seems to work, ask you can see, the errors demonstrate that with a complaint reduce it will produce the desired errors if the types do not match as specified.

Maybe I'm misunderstanding something? Thanks

@sledorze
Copy link
Collaborator

@babakness the actual order favors developper experience, meaning it is easier to fill in the reducer initial value and then fill in the reduce function as all type parameters have been discovered by the compiler.
Using the opposite order would still type check correctly but developper experience is not as nice because when writing the reduce function, all type params have not been discovered yet.

@babakness
Copy link
Contributor Author

Hi @sledorze

Wouldn't the developer experience be addressed by have two methods as such

ap

ap<B>(fab: Option<(a: A) => B>): Option<B> {

ap_

ap_<B, C>(this: Option<(b: B) => C>, fb: Option<B>): Option<C> {

Or perhaps other names.

Then implementing the methods named per Fantasyland specs for the sake of inter-operability between libraries? Again, still having other methods for sake of developer experience.

Note: I believe the current ap matches Fantasyland whereas many libraries implement the order of ap_ as their ap for similar sentiment as experience or precedence.

I also very curious about the mentioned developer experience! I guess I'm used to Array.prototype.reduce. If you've the time, could you illuminate the subject with an example where the flipped order is preferable?

@raveclassic
Copy link
Collaborator

Related #204

@gcanti
Copy link
Owner

gcanti commented Jun 26, 2018

Closing this as @sledorze's answer explains the rationale of the current choice

@gcanti gcanti closed this as completed Jun 26, 2018
@ElamuruganGR
Copy link

ElamuruganGR commented Oct 25, 2021

Hey, I want to know how to use foldMap of Option. Can i get any simple examples here?
Also if there is any website or url having examples of this fp-ts, pls mention here. It will be very useful.

@samhh
Copy link
Contributor

samhh commented Oct 25, 2021

@ElamuruganGR Not tested but eyeballing it this looks right.

export declare const foldMap: <M>(M: Monoid<M>) => <A>(f: (a: A) => M) => (fa: Option<A>) => M
import * as O from 'fp-ts/Option'
import * as Str from 'fp-ts/string'
import { pipe } from 'fp-ts/function'

declare const x: Option<string>
pipe(x, O.foldMap(Str.Monoid)(x => x + '!'))

@ElamuruganGR
Copy link

Thanks @samhh Its working.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants