我想用Option代替switch。我试过Alt.altAll
,它工作得很好:
function foo(a: number) {
return alt.altAll(O.Alt)<string>(O.none)([
O.fromPredicate(() => a >= 85)('A'),
O.fromPredicate(() => a >= 75)('B'),
O.fromPredicate(() => a >= 75)('C'),
O.some('D'),
])
}
但它总是评估整个选项数组,而不是短路,所以我想知道是否有一种方法来实现下面的逻辑?谢谢!
// I don't want to use Option.alt because that would add one more level of nesting.
function foo(a: number) {
return alt.lazyAltAll(O.Alt)<string>(O.none)([
() => O.fromPredicate(() => a >= 85)('A'),
() => O.fromPredicate(() => a >= 75)('B'),
() => O.fromPredicate(() => a >= 75)('C'),
() => O.some('D'),
])
}
如果你想实现一个功能类似于一个现有的,它可以帮助看源代码,例如altAll
。稍微修改一下:
import type {Alt, Alt1, Alt2, Alt2C, Alt3, Alt3C, Alt4} from 'fp-ts/Alt'
import type {HKT, Kind, Kind2, Kind3, Kind4, URIS, URIS2, URIS3, URIS4} from 'fp-ts/HKT'
import type {Lazy} from 'fp-ts/function'
// type Lazy<A> = () => A
function lazyAltAll<F extends URIS4>(F: Alt4<F>): <S, R, E, A>(startWith: Kind4<F, S, R, E, A>) => (as: readonly Lazy<Kind4<F, S, R, E, A>>[]) => Kind4<F, S, R, E, A>
function lazyAltAll<F extends URIS3>(F: Alt3<F>): <R, E, A>(startWith: Kind3<F, R, E, A>) => (as: readonly Lazy<Kind3<F, R, E, A>>[]) => Kind3<F, R, E, A>
function lazyAltAll<F extends URIS3, E>(F: Alt3C<F, E>): <R, A>(startWith: Kind3<F, R, E, A>) => (as: readonly Lazy<Kind3<F, R, E, A>>[]) => Kind3<F, R, E, A>
function lazyAltAll<F extends URIS2>(F: Alt2<F>): <E, A>(startWith: Kind2<F, E, A>) => (as: readonly Lazy<Kind2<F, E, A>>[]) => Kind2<F, E, A>
function lazyAltAll<F extends URIS2, E>(F: Alt2C<F, E>): <A>(startWith: Kind2<F, E, A>) => (as: readonly Lazy<Kind2<F, E, A>>[]) => Kind2<F, E, A>
function lazyAltAll<F extends URIS>(F: Alt1<F>): <A>(startWith: Kind<F, A>) => (as: readonly Lazy<Kind<F, A>>[]) => Kind<F, A>
function lazyAltAll<F>(F: Alt<F>): <A>(startWith: HKT<F, A>) => (as: readonly Lazy<HKT<F, A>>[]) => HKT<F, A>
function lazyAltAll<F>(F: Alt<F>): <A>(startWith: HKT<F, A>) => (as: readonly Lazy<HKT<F, A>>[]) => HKT<F, A> {
return startWith => as => as.reduce(F.alt, startWith)
}
如果你只对Option
使用它,你只需要<F extends URIS>(F: Alt1<F>)
过载。其他的重载是针对像Either
这样有多于一个类型参数的类型。
这可以工作,因为F.alt
已经支持有第二个惰性参数,所以你可以像O.Alt.alt(O.none, () => O.some(1))
那样做。