用于递归函数的流注释

时间:2018-04-24 03:31:56

标签: javascript functional-programming flowtype

我对如何为这样的函数编写流类型注释感兴趣:

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的回答并不合适,因为他更改了源代码而这不是重点。

3 个答案:

答案 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)

UPDATE:

不确定是否可行,评论中的链接是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" )}` );