F# 在映射中查找第一个参数
我一直在Euler项目上练习我的F#技能。在做第19题时(冷静之后的一次剧烈的反高潮),我发现自己需要对数字列表执行模7运算。我试过这个:F# 在映射中查找第一个参数,f#,F#,我一直在Euler项目上练习我的F#技能。在做第19题时(冷静之后的一次剧烈的反高潮),我发现自己需要对数字列表执行模7运算。我试过这个: List.map ((%) 7) 结果却列错了号码。这是因为List.map绑定了第二个参数,因此它没有计算n%7,而是计算了7%n。是否有一种方法可以使List.map绑定第一个参数,或者有一种标准方法可以翻转两个参数 我知道我可以使用fun->n%7而不是(%)7,但我希望有一个较短的解决方案。您可以为此定义翻转: namespace Microsof
List.map ((%) 7)
结果却列错了号码。这是因为List.map
绑定了第二个参数,因此它没有计算n%7,而是计算了7%n。是否有一种方法可以使List.map
绑定第一个参数,或者有一种标准方法可以翻转两个参数
我知道我可以使用
fun->n%7
而不是(%)7
,但我希望有一个较短的解决方案。您可以为此定义翻转
:
namespace Microsoft.FSharp.Core
module Operators =
let flip f x y = f y x
在函数式编程语言中,这是一种相当常见的方法。例如,Haskell还有一个
翻转
功能。翻转功能:
let inline flip f a b = f b a
通常用于此任务。现在您可以将flip(%)7
直接传递到List.map
这就是所谓的无点风格,在Haskell很流行,但在F#社区并不常见。问题是,在许多情况下,它可能会使程序难以阅读和维护。其他人已经指出,这可以通过定义Haskell的
flip
函数来实现。但是,我建议显式地使用lambda函数编写代码,或者使用列表理解(更简短,避免显式lambda):
最好定义一个助手函数moduleby
,其行为类似于带有翻转参数的%
:
let moduloBy n input = input % n
inputs |> List.map (moduloBy 7)
原因是可读性。虽然Euler问题是一个很有趣的例子,但编写易于理解的代码很重要。在F#中,这一点更为重要,因为在F#中,编写真正难以理解的代码相当容易。我想您会同意,阅读上述代码片段比阅读容易(而且,使用flip
的解决方案也不会明显缩短):
我希望这样的事情已经被定义了。谢谢,我加的。现在接受答案还为时过早。我稍后会接受。你也应该把它变成
内联的。FP的一个缺点是可以编写一些真正难以理解的代码。一旦你习惯了flip
,它应该比fun n->n%7
更清晰。它当然比fold更容易适应…@zmbq我不认为无点样式比显式lambda更清晰,除了简单的部分应用程序或函数组合。如果你是一个在Haskell程序员团队中工作的熟练函数式程序员,那就没问题了,但除此之外,我更喜欢另一种选择。旁注:问题19可以用非常有限的数学以纯函数的方式完美地解决-只要+1
。看看你可以怎么检查。它大约和问题18的解决方案一样长…(社论)“我知道我可以用fun->n%7
而不是(%)7
,但我希望有一个更短的解决方案。”这是一种在哈斯凯尔人中很常见的疾病,希望找到深奥的语言特性或库函数,使您能够从代码中删除三个字符。我无法理解这种心态。我想我应该受宠若惊,因为你称我为哈斯凯勒。。。
let moduloBy n input = input % n
inputs |> List.map (moduloBy 7)
inputs |> List.map ((flip (%)) 7)