在地图中查找第一个参数

时间:2012-03-20 12:17:38

标签: f#

我一直在Project Euler上练习F#技能。在做问题19(在酷problem 18之后发生激烈的反对声)时,我发现自己需要在数字列表上执行模7运算。我试过这个:

List.map ((%) 7)

最终得到了错误的数字列表。那是因为List.map绑定了第二个参数,所以不是计算n%7而是计算7%n。有没有办法让List.map绑定第一个参数,或者是翻转这两个参数的标准方法?

我知道我可以使用fun n->n%7代替(%) 7,但我希望有更短的解决方案。

3 个答案:

答案 0 :(得分:3)

其他人已经指出,这可以通过从Haskell定义flip函数来完成。但是,我建议使用lambda函数或使用列表推导显式编写代码(更短并避免使用显式lambdas):

inputs |> List.map (fun n-> n % 7)
[ for n in inputs -> n % 7 ]

使用翻转的参数定义一个行为类似moduloBy的辅助函数%可能是个好主意:

let moduloBy n input = input % n
inputs |> List.map (moduloBy 7)

原因是可读性。虽然欧拉问题是玩具的例子,但编写易于理解的代码非常重要。这在F#中更为重要,因为编写非常难以理解的代码非常容易。我认为您同意阅读上述代码段比阅读更容易(并且使用flip的解决方案也不会明显缩短):

inputs |> List.map ((flip (%)) 7)

答案 1 :(得分:2)

您可以为此目的定义flip

namespace Microsoft.FSharp.Core
module Operators =
    let flip f x y = f y x

这是在函数式编程语言中这样做的一种相当常见的方式。例如,Haskell还有一个flip函数in its Prelude

答案 2 :(得分:2)

flip功能:

let inline flip f a b = f b a

通常用于此任务。现在,您可以将flip (%) 7直接传递给List.map

这称为无点样式,在Haskell中很流行但在F#社区中并不常见。问题是,在许多情况下,它可能使程序难以阅读和难以维护。