用于列表平均值计算的自定义组合子类型确认:是否为Starling_组合子?
确认你的组合子确实是Starling_组合子
没错,你的myCombinator完全符合Starling_组合子(也常被记作ψ或S')的定义,咱们一步步拆解验证:
1. 你的组合子类型与行为分析
先看你写的JavaScript实现:
const myCombinator = f => g => h => x => f(g(x))(h(x));
对应的类型签名你已经准确推导出来了:
myCombinator :: (b -> c -> d) -> (a -> b) -> (a -> c) -> a -> d
用通俗的话解释这个逻辑:
- 它先接收一个二元函数
f(需要两个参数才能输出结果) - 接着接收两个一元函数
g和h(各自只需要一个参数就能输出结果) - 最后接收一个共享输入
x,把x分别传给g和h得到两个中间结果,再把这两个结果传给f,最终得到输出值
2. 为什么不是Blackbird组合子
你提到最初有人说这是Blackbird,咱们对比Blackbird的类型签名:
blackbird :: (c -> d) -> (a -> b -> c) -> a -> b -> d
Blackbird的作用是把一个一元函数“套”在一个二元函数的输出上——二元函数先接收两个参数得到c,再把c传给一元函数得到d。这和你的组合子逻辑完全相反:你的组合子是把两个一元函数的输出喂给二元函数,所以确实不是Blackbird。
3. 与Starling_组合子的完全匹配
Starling_组合子的标准类型签名就是:
starling_ :: (b -> c -> d) -> (a -> b) -> (a -> c) -> a -> d
它的核心行为就是共享一个输入参数给两个一元函数,再把它们的结果交给一个二元函数处理,这正好和你用它计算平均值的场景完美契合:
div是那个二元函数(接收总和和长度,返回平均值)sum和length是两个一元函数(都接收数组,分别返回总和和长度)average组合后,接收数组就能自动完成“求和→取长度→做除法”的流程
你的代码运行结果也验证了这一点:average([1,2,...,9])会返回5,完全符合预期。
内容的提问来源于stack exchange,提问作者Fogmeister
相关产品推荐
相关产品推荐

