F# 如何避免改变参数顺序
我目前正在做的一些练习。其中一个练习是将序列中的所有数字相加,这些数字是不同序列中一个或多个数字的倍数。将问题分解为更小的函数似乎是个好主意,我提出了以下建议:F# 如何避免改变参数顺序,f#,F#,我目前正在做的一些练习。其中一个练习是将序列中的所有数字相加,这些数字是不同序列中一个或多个数字的倍数。将问题分解为更小的函数似乎是个好主意,我提出了以下建议: 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.fi
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
参数“烘焙”到我的(任意)多个
函数中。但是这个代码没有按照我希望的方式工作,因为Seq.exists(n的倍数)
实际上应用n
作为我的m
参数
我如何重构此代码而不必反转我的multipleOf
函数的参数顺序
注意:我想要一个在我的
anyMultipleOf
函数中使用我的multipleOf
函数的解决方案。此解决方案可行,但不重用我的第一个功能:
let anyMultipleOf (m: int list) n =
m
|> Seq.exists (fun x -> n % x = 0)
您可以自己定义一个函数,只需这样做:
以相反的顺序获取一个函数和两个参数,并返回将参数按正确顺序应用于函数的结果
let flip f y x = f x y
虽然我不清楚为什么不重新定义
anyMultipleOf
以将列表作为最后一个参数,但始终可以使用flip
:
let flip f x y = f y x
这个函数,但不是在FSharp.Core中,这就是您必须自己定义它的原因
例如,flip anyMultipleOf
返回一个类型为int->int list->bool
的函数,如果我理解正确,这就是您想要的。我确实输入了使用flip
的建议,但显而易见的是:
let anyMultipleOf (m: int list) n =
m
|> Seq.exists (fun x -> multipleOf x n)
flip
是一个很好的工具,但是翻转函数的管道读起来很痛苦。但是multipleOf
和anyMultipleOf
都应该以相反的顺序使用参数。参数的定义从更一般到更具体。重复使用x的(任意)倍数是有意义的,而不是我目前认为的那样,我认为这个过程恰恰相反。比如根据部分应用的序列检查所有值:let anyMultipleOfMyNumbers=anyMultipleOf[3;5;7]
这一个也很有效:let filterMultiplesOf5 numlist=numlist |>Seq.filter(multipleOf 5)
虽然它与flip相同,但我更喜欢您的解决方案。它在参数的去向上更加明确,并且当有更多的参数时也更容易阅读。