如何避免更改参数顺序

时间:2016-08-10 17:13:30

标签: f#

我目前正在做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)

3 个答案:

答案 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