2016-10-01 46 views
1

我借这个声明tail功能从Ramda死代码(Ramda型decelration)打破流量

declare function tail<T,V:Array<T> | string>(xs: V): V; 

我有一个类型Query这基本上是一个ReaderT Promise单子:

// @flow 

class Query<C, T> { 
    run: (config: C) => Promise<T>; 
    constructor(runner : (config: C) => Promise<T>) { 
    this.run = runner 
    } 
    bind <U>(f : ((a: T) => Query<C, U>)) : Query<C, U> { 
    return new Query(config => this.run(config).then(x => f(x).run(config))) 
    } 
    map <U>(f : (a: T) => U) : Query<C, U> { 
    return new Query(config => this.run(config).then(f)) 
    } 
} 

使用此definition Flow正确无法检查此表达式:

new Query(config => Promise.resolve(config + 1)) // config is {init: number} 
.run({init: 2}).then(console.log) 

Flow console

但是,当我限定使用声明tail功能(即使我不调用sequence)一个sequence功能,流类型检查上述不正确的表达而没有任何错误:

const sequence = <C> (queries : Array<Query<C, any>>) : Query<C, Array<any>> => { 
    if (queries.length == 0) { 
    return new Query(t => Promise.resolve([])) 
    } else { 
    return queries[0].bind(x => sequence(tail(queries)).map(ys => [x].concat(ys))) 
    } 
} 

Flow console

我应该注意,如果我将tail的类型更改为:

declare function tail<T,V:Array<T>>(xs: V): V; 

(删除总和型)

Flow console

难道我得到的东西错了或者是它在流中的错误?

回答

2

似乎绝对是一个错误。我设法缩短失败的测试

// @flow 

declare function tail<T,V:Array<T> | string>(xs: V): V; 

class Query<C, T> { 
    run: (config: C) => Promise<T>; 
    constructor(runner : (config: C) => Promise<T>) { 
    this.run = runner 
    } 
    chain <U>(f : (a: T) => Query<C, U>) : void { 
    } 
} 

function wat<C, T>(queries : Array<Query<C, T>>) : void { 
    tail(queries) 
} 

// $ExpectError 
new Query(config => Promise.resolve(config + 1)).run({init: 2}) 
+0

已报告的错误:https://github.com/facebook/flow/issues/2565(使用不同的代码段一但非常类似的情景) – homam