F#是否存在将值管道到函数最后一个参数的运算符或自定义方法?
你原有实现未达预期的核心原因是仅在自定义类型中定义了运算符重载,没有补充全局的inline运算符绑定让F#的类型系统能正确解析重载。正确的完整实现如下:
type LastPipedArg = static member inline (|&>)( f: 'a1 -> 'r, lastArg: 'a1) = f lastArg static member inline (|&>)(f: 'a1 -> 'a2 -> 'r, lastArg: 'a2) = fun a1 -> f a1 lastArg static member inline (|&>)( f: 'a1 -> 'a2 -> 'a3 -> 'r, lastArg: 'a3) = fun a1 a2 -> f a1 a2 lastArg static member inline (|&>)(f: 'a1 -> 'a2 -> 'a3 -> 'a4-> 'r, lastArg: 'a4) = fun a1 a2 a3 -> f a1 a2 a3 lastArg // 补充全局运算符绑定,通过SRTP匹配上述重载 let inline (|&>) f lastArg = ^LastPipedArg : (static member (|&>) : ^f * ^lastArg -> ^result) (f, lastArg)
上述实现完全符合你的需求:
- 左结合规则和F#默认的
|>运算符保持一致 - 每次运算都会将右侧值作为左侧柯里化函数的最后一个参数传入,返回补全最后一个参数后的新函数
你的示例代码可以直接运行:
let downloadAndDecompress = download |&> decompressStream |&> writeToTempFile // 调用示例,返回Task<string>类型的临时文件路径 downloadAndDecompress "https://example.com/test.gz"
这类"最后一个参数传入管道"在F#社区有较多类似实现,常被用于连续的CPS(续体传递风格)函数组合,和你场景中的scoped参数设计完全匹配。如果需要支持更多参数的函数,仅需要在LastPipedArg类型中补充对应参数数量的重载即可。
内容的提问来源于stack exchange,提问作者Gabriel Guillermo
相关产品推荐
相关产品推荐

