Typescript 两种功能的无点样式”;“合并”;(未撰写)

Typescript 两种功能的无点样式”;“合并”;(未撰写),typescript,functional-programming,pointfree,fp-ts,Typescript,Functional Programming,Pointfree,Fp Ts,我正在用TypeScript做这件事,但如果能用另一种具有FP能力的语言做出响应,我会很满意的 假设我有constfoo=(a:a)=>M和constbar=(b:b)=>N。我希望“并行”运行这些函数(不必是实际的并行IO,但它们并不相互依赖),而是以无点方式定义“组合” 如果它们实际上是可组合的(比如说a返回B而不是M),我可以编写 const composed = flow(foo, bar) // (a:A) => N 相反,我想用某种方法将它们结合起来(我们称之为magicCo

我正在用TypeScript做这件事,但如果能用另一种具有FP能力的语言做出响应,我会很满意的

假设我有
constfoo=(a:a)=>M
constbar=(b:b)=>N
。我希望“并行”运行这些函数(不必是实际的并行IO,但它们并不相互依赖),而是以无点方式定义“组合”

如果它们实际上是可组合的(比如说
a
返回
B
而不是
M
),我可以编写

const composed = flow(foo, bar) // (a:A) => N
相反,我想用某种方法将它们结合起来(我们称之为
magicCompose
),这样我的无点风格就可以

const newFn = magicCompose(foo, bar) // (a:A, b:B) => [M,N] or ({a:A, b:B}) => [M,N] or (p:[A,B]) => [M,N]
这有可能吗

在TypeScript中使用
fp-ts
,我有了
sequenceT
,它可以让我把它们当作读卡器,并像这样组合起来

const _ = sequenceT(reader)(foo, bar)
但是,如果
foo
bar
采用不同的参数,则此选项无效。我可以使用
local:(E=>R)=>(Reader)=>Reader
,但我必须打破点自由来写

const _ = sequenceT(reader)(
  local((params:{a:A,b:B}) => params.a)(foo),
  local((params:{a:A,b:B}) => params.b)(bar)) // Reader<{a:A,b:B}, [M,N]>

但这看起来像是为了获得分数而作弊。

我对fp ts不太熟悉,但这是我的第一个想法-你可以将
foo
bar
变成thunks。thunk是一个不带参数的函数-通常它是由一个带参数的函数组成的,所以你可以只做
partial(foo,A)
就可以得到一个。现在有两个函数在执行时生成结果。也许有一种方法可以让你更容易处理它们,因为你不需要管理输入。为什么你这么热衷于写这篇文章呢?(顺便说一句,在哈斯凯尔,它被称为)只是一个练习PF的借口,因为我是新手。我一直在编写一个API库,其中我有一个
fn1=(a:a)=>B
,它由其他函数组成,最终是
export const apiCall=(a:a)=>pipe(fn1(a),…)
,我喜欢能够减少显式提供参数的次数。使用fp ts,我可以
导出const apiCall=flow(fn1,…)
,并且从不提供参数。因此,我避免了重复,这使重构更容易。这就是我对PF感兴趣的原因,现在我正在努力学习。就在这种情况下,这并不是那么简单。我有两个函数依赖于一些初始参数的一部分,我希望避免
export const apiCall=(a:a,b:b)=>combine(fnTakingA,fnTakingB)
如果可能的话,现在我决定把它们当作
读取器
,我可以使用
Reader.local
来改变环境
{a,b}
传递给
fnA
fnB
,这解决了我的问题。只是感觉不雅。我对fp ts不太熟悉,但这里是我对此的第一个想法-你可以将
foo
bar
变成thunks。thunk是一个不带参数的函数-通常它是由一个带参数的函数组成的,所以你可以只做
partial(foo,A)
就可以得到一个。现在有两个函数在执行时生成结果。也许有一种方法可以让你更容易处理它们,因为你不需要管理输入。为什么你这么热衷于写这篇文章呢?(顺便说一句,在哈斯凯尔,它被称为)只是一个练习PF的借口,因为我是新手。我一直在编写一个API库,其中我有一个
fn1=(a:a)=>B
,它由其他函数组成,最终是
export const apiCall=(a:a)=>pipe(fn1(a),…)
,我喜欢能够减少显式提供参数的次数。使用fp ts,我可以
导出const apiCall=flow(fn1,…)
,并且从不提供参数。因此,我避免了重复,这使重构更容易。这就是我对PF感兴趣的原因,现在我正在努力学习。就在这种情况下,这并不是那么简单。我有两个函数依赖于一些初始参数的一部分,我希望避免
export const apiCall=(a:a,b:b)=>combine(fnTakingA,fnTakingB)
如果可能的话,现在我决定把它们当作
读取器
,我可以使用
Reader.local
来改变环境
{a,b}
传递给
fnA
fnB
,这解决了我的问题。只是觉得不雅。
const _ = sequenceT(reader)(
  local(_a.get)(foo),
  local(_b.get)(bar)) // Reader<{a:A,b:B}, [M,N]>