我对如何为这样的函数编写流类型注释感兴趣:
const Box = x => ({
map: f => Box(f(x)),
fold: f => f(x),
});
我想,类型注释应该使用泛型 功能用法示例:
const getRandomColor = (): string =>
Box(Math.random())
.map(x => x * 0xFFFFFF)
.map(Math.floor)
.map(x => x.toString(16))
.fold(x => `#${x.padStart(0, 6)}`);
P.S。:如果不可能,请写一个解释为什么不可能。
很遗憾,@ Isitea的回答并不合适,因为他更改了源代码而这不是重点。
答案 0 :(得分:4)
@ Jared的答案只会让我们分开,但要注意它 强制执行的事情。
我们如何使用flow generics
来编写它netcat
给定一个简单的函数和我们的框的值,我们应该能够验证是否强制执行泛型类型约束
const Box = <A>(x:A): Box<A> => {
return {
map: <B>(f: A => B): Box<B> => Box(f(x)),
fold: <B>(f: A => B): B => f(x),
}
}
截至目前,这已经破裂,并且在流程中不起作用。 @mrkev向我们展示了使用类
的解决方法const numberToString = (x: number) : string =>
String (x)
const b : Box<string> =
new Box("1")
b.map(numberToString) // wups! flow doesn't mind!
@thehogfather与预先定义的class Box<A> {
x: A
constructor (x: A) { this.x = x }
map<B>(f: A => B): Box<B> { return new Box(f(this.x)) }
fold<B>(f: A => B): B { return f(this.x) }
}
const numberToString = (x: number) : string =>
String (x)
const stringToNumber = (x: string): number =>
Number (x)
const b : Box<string> =
new Box("1")
// flow accepts this valid program
b.map(stringToNumber)
// flow rejects this invalid program
b.map(numberToString)
// ^ Cannot call `b.map` with `numberToString` bound to `f` because number [1] is incompatible with string [2] in the first argument.
分享另一种选择。这更接近原始形式,但需要耗费大量的打字 - 如果流程提供更有能力的类型系统,则需要2倍的 。无论如何它都有效,所以我们不允许抱怨。
type
答案 1 :(得分:2)
不确定是否可行,评论中的链接是map
方法的反例。
是的!确实有可能:
const Box = <T1>(x:T1): Box<T1> => {
return {
map: <T2>(f): Box<T2> => Box(f(x)),
fold: <T3>(f): T3 => f(x),
};
};
function takesBoxedString (b: Box<string>):string { return b.fold(s => s + '') }
let boxedNum = Box(3);
let boxedString = Box('foo');
takesBoxedString(boxedString); // fine
takesBoxedString(boxedNum); // compiler complains
当我开始这个时,我对流量仿制药一无所知,但男孩,我现在对他们有更好的欣赏。这是playground。
答案 2 :(得分:0)
我不确定你想要什么。
如果您正在使用&bab;&#39;流式检查器,我认为以下代码是您想要的。(使用flow.org测试)
/* @flow */
const Box = ( x: string | number ): Box => ( {
toNumber: ( f: Function ): Box => Box( f( x ) ),
toString: ( f: Function ): string => f( x )
} );
const getRandomColor = (): string =>
Box( Math.random() )
.toNumber( ( x: number ): number => x * ( 2 ** 32 ) )
.toNumber( Math.floor )
.toString( ( x: number ): string => x.toString( 16 ) )
.toString( ( x: string ): string => `#${x.padStart( 6, "0" )}` );