【发布时间】:2019-10-28 21:40:57
【问题描述】:
我有如下所示的一元数据结构:
export abstract class Data<A> {
static initial<A>(): Data<A> {
return new Initial<A>()
}
static failed<A>(error?: any): Data<A> {
return new Failed<A>(error)
}
static loaded<A>(value: A): Data<A> {
return new Loaded<A>(value)
}
static loading<A>(): Data<A> {
return new Loading<A>()
}
static getData<A>(data: Loaded<A>): A {
return data.getData()
}
constructor(public readonly kind: Kind) {}
abstract map<B>(f: (a: A) => B): Data<B>
abstract chain<B>(f: (a: A) => Data<B>): Data<B>
abstract flatMap<B>(f: (a: A) => Data<B[]>): Data<B>[]
}
Initial、Failed、Loaded 和 Loading 是我的类型的四种不同“形状”。
有时在我的代码中我会得到一个Data<A>[],我想根据A 上的条件进行过滤。我目前的实现是这样的:
static filter<A>(data: Data<A>[], pred: (a:A) => boolean): Data<A>[] {
return data.filter(datum => {
if(datum.isLoaded()) {
return pred(datum.data)
}
return false
})
}
大部分代码使用链式方法,例如:
data.map(...).filter(...).doThis().doThat()
但由于static,有时订单会变得混乱:
Data.filter(data.map(...).flatMap(...), myPredicate).map(...).doThis(...) ........
我想知道是否有办法使这个函数成为非静态函数并使用“流畅”的链接方法?
我应该为此扩展数组的原型吗?
【问题讨论】:
-
isLoaded()和Data的data属性在哪里定义?还有Initial、Failed、Loaded和Loading?通常,当您在问题中包含代码时,它应该构成minimal reproducible example,这样代码的唯一问题就是您要询问的问题。这有时意味着删除对外部依赖项的引用并用精简/模拟/虚拟版本替换它们。理想情况下,有人能够将您的代码放入独立的 IDE(如 this)并立即着手对其进行修改以制定潜在的解决方案。 -
我删除了
isLoaded()、isLoading()等谓词来缩短代码,我认为从他们的名字中可以清楚地看出他们只是断言Data<A>处于什么状态。但是做一个在线代码沙箱也不错。感谢您的意见。
标签: javascript arrays typescript monads