Add fantasy land support #55
Comments
I implemented Option and Either based on what you did in Another thing — a bit of a blasphemy for pure fantasy land folks — can we think of a method similar to |
If we go the fantasy-land route then yes
We can define overloadings though it's not the same (augmentations can be distributed while overloadings are centralised) Example with // file Functor.js
import type { Option, URI as OptionURI } from './Option'
export interface Functor<F> {
map<A, B>(f: (a: A) => B, fa: HKT<F, A>): HKT<F, B>
}
// more overloadings here...
declare function lift<A, B>(functor: Functor<OptionURI>, f: (a: A) => B): (fa: Option<A>) => Option<B>
export function lift<F, A, B>(functor: Functor<F>, f: (a: A) => B): (fa: HKT<F, A>) => HKT<F, B> {
return fa => functor.map(f, fa)
}
Not sure what you gain from merging |
Actually we could also implement a export function fromNullable<A>(a: ?A): Option<A> {
return a == null ? none : some(a)
}
export function toNullable<A>(fa: Option<A>): ?A {
return fa instanceof Some ? fa.value : null
} and then alias them to [DISCLAIMER] I switched to TypeScript and I think I won't look back anytime soon, so I'll dedicate much less time to flow-static-land |
@gcanti do you have any write ups anywhere describing why you made the switch? I thought that the type variance support of flow would play nicer with some advanced FP concepts, but perhaps I am misguided. :) |
@ctrlplusb No, I only have a list of pros and cons (presented in an internal meeting at buildo) half in english and half in italian. The gist is that TypeScript is a great tool from a pragmatic point of view. Also indexed types are awesome.
Indeed, that and its advanced type inference are what I miss the most, especially in the context of functional programming. |
Is this something you're still considering? While I know you don't prefer point-free programming, I'd love to see this! @DrBoolean export const map = <A, B>(f: A => B): (HKTOption<A> => Option<B>) => fa => {
return ((fa: any): Option<A>).map(f)
}
const foo = compose(
map(log),
map(double),
some,
)
foo(10) // Some(20) |
Seems like this should error? console.log(maybeDouble(some(''))) // No Error |
This fixes the above error... class None {
__hkt: URI
__hkta: any
// ...
} to... class None<A> {
__hkt: URI
__hkta: A
// ...
} The |
With the motivation of making things more clear & approachable, I'm curious what you all think of the following changes:
// @flow
interface Kind<F, A> {
__type: [ F, A ]
}
interface Functor<F> {
map<A, B>(f: A => B, fa: Kind<F, A>): Kind<F, B>
}
type Maybe<A> = Nothing<A> | Just<A>
class Nothing<A> implements Kind<'Maybe', A> {
__type: [ 'Maybe', A ]
static of(): Maybe<A> {
return new Nothing()
}
map<B>(f: A => B): Maybe<B> {
return (Nothing.of(): any)
}
inspect(): string {
return this.toString()
}
toString(): string {
return 'Nothing'
}
}
class Just<A> implements Kind<'Maybe', A> {
__type: [ 'Maybe', A ]
value: A
static of(value: A): Maybe<A> {
return new Just(value)
}
constructor(value: A) {
this.value = value
}
map<B>(f: A => B): Maybe<B> {
return Just.of(f(this.value))
}
inspect(): string {
return this.toString()
}
toString(): string {
return `Just(${JSON.stringify(this.value)})`
}
}
export function map<A, B>(f: A => B, fa: Kind<'Maybe', A>): Maybe<B> {
return ((fa: any): Maybe<A>).map(f)
}
const double = (n: number): number => n * 2
const length = (s: string): number => s.length
function lift<F, A, B>(functor: Functor<F>, f: A => B): Kind<F, A> => Kind<F, B> {
return fa => functor.map(f, fa)
}
const maybeDouble = lift({ map }, double)
console.log(maybeDouble(Just.of(10))) // Just(20)
console.log(Just.of(1).map(double)) // Just(2)
console.log(Nothing.of().map(double)) // Nothing
console.log(Just.of(1).map(length)) // error: number. This type is incompatible with the expected param type of string
|
Note that flow now has $Values and $ElementType can help too Also, if you use comment syntax, you can avoid unnecessarily real code - no |
Proof of concept (borrowed from fp-ts)
The text was updated successfully, but these errors were encountered: