我目前正在做exercism.io的一些练习。其中一个练习是将序列中的所有数字相加,该序列是来自不同序列的一个或多个数字的倍数。将问题拆分成较小的函数似乎是一个好主意,我想出了这个:
let multipleOf m n =
n % m = 0
let anyMultipleOf (m: int list) n =
m
|> Seq.exists (multipleOf n)
let sumOfMultiples m n =
[1..n-1]
|> Seq.filter (anyMultipleOf m)
|> Seq.sum
我的想法是,我可以使用部分申请来"烘烤"我的m
函数中的(any)multipleOf
参数。但是这段代码并不像我想要的那样工作,因为Seq.exists (multipleOf n)
实际上将n
用作我的m
参数。
如何在不必反转multipleOf
函数的参数顺序的情况下重构此代码?
注意:我想要一个在我的multipleOf
函数中使用anyMultipleOf
函数的解决方案。这个解决方案有效,但没有重用我的第一个功能:
let anyMultipleOf (m: int list) n =
m
|> Seq.exists (fun x -> n % x = 0)
答案 0 :(得分:4)
我 输入了使用flip
的建议,但显而易见的是:
let anyMultipleOf (m: int list) n =
m
|> Seq.exists (fun x -> multipleOf x n)
flip
是一个很好的工具,但翻转函数的管道很难阅读。
答案 1 :(得分:3)
虽然我不清楚为什么你不重新定义flip
以将列表作为最后一个参数,但你总是可以使用let flip f x y = f y x
:
flip anyMultipleOf
此函数exists in Haskell,但FSharp.Core中没有,这是您必须自己定义它的原因。
例如,int -> int list -> bool
会返回类型为{{1}}的函数,如果我正确理解了问题,那就是你想要的。
答案 2 :(得分:2)
你可以自己定义一个能够做到这一点的功能:
以相反的顺序获取一个函数和两个参数,并返回以正确的顺序将参数应用于函数的结果
let flip f y x = f x y