首页 > 解决方案 > 当第二个函数返回第一个函数的值和第一个函数的参数时,两个函数的无点组合

问题描述

假设我正在编写一个函数来进行 HTTP 调用以获取数据。我已将 API 调用分解为我编写的更小的函数:

const buildPayload = (inputs:Inputs) => reader.of({...inputs, some:'bar'}) // (inputs:Inputs) => Reader<unknown, Payload>
const buildUrl = reader.of('path/to/call') // Reader<unknown, string> (will be Reader<BaseUrl, string>)
const options = reader.of({options:{headers: /*...*/ }}) //Reader<unknown, AxiosOptions>

// (inputs:Inputs) => reader<unknown, [string,AxiosOptions,Payload]>
const fetchDeps = flow(buildPayload, _ => sequenceT(reader)(buildUrl, options, _))

// (inputs:Inputs) => reader<unknown, ()=>AxiosResponse<any>>
const fetchThunk = flow(fetchDeps, reader.chain(deps => ()=>axios.post(...deps)))

// And so forth
export const apiCall = flow(fetchThunk, /*...*/) // (inputs:Inputs) => ReaderTaskEither<TokenAndBaseUrl, DomainError, RequestedApiData>

使用flow我已经设法最小化定义输入参数的频率。它只是一个地方,在buildPayload,我没有任何隐含的any论点)。如果出现新需求,这使得更改参数变得容易:更新一个地方,更改会在其余代码中级联。我认为这被称为“无点编程”。

当每一步都依赖于前一步而不依赖于其他步骤时,这很容易。但是假设流程中const foo = (a:A)=>B的第一步是,第二步是const bar = (a:A,b:B)=>C这样,第一步取决于第一步的结果,但也需要与第一步相同的参数。

我怎样才能做到这一点并且仍然是免费的(假设我正确使用了该术语)?

flow(foo, bar)不起作用,因为 thenbar需要接受的返回值foo作为其参数。

我可以将它们定义为foo = (a:A) => ...然后bar = (a:A, b:B) => ...

export const apiCall = (inputs:A) => pipe(foo(inputs), _ => bar(inputs, _), /*...*/)

但现在我必须(inputs:A)在三个地方定义:foobarapiCall. 如果我更改参数,我必须更新三个不同的函数参数列表。

标签: typescriptfunctional-programmingcompositionpointfreefp-ts

解决方案


推荐阅读