将元组内联作为参数拆分为具有非元组参数的函数

时间:2013-06-07 10:15:07

标签: f#

我有一个带两个参数的函数,例如:

let f a b = a = b

然后我有第二个函数返回一个元组:

let g = (a, b)

我想将元组中的a和b作为参数传递到f中的一行。我可以在两个语句中完成它,但我想这样做的原因是我的调用函数执行或者我宁愿不调用f,除非第一种情况是假的,以节省不必要的处理。

let calling =
  someboolean || 
  f g // want to split result of g to parameters for f without calling g twice

有关如何执行此操作的任何提示?我知道我可以选择一个元组,但我想保留currying的选项。

我希望我解释得这么好。 :)

4 个答案:

答案 0 :(得分:8)

你也可以这样做:

let calling = someBoolean || g ||> f

由于:

(||>) : ('a * 'b -> ('a -> 'b -> 'c) -> 'c)

(同样(|||>) : ('a * 'b * 'c -> ('a -> 'b -> 'c -> 'd) -> 'd)

答案 1 :(得分:5)

您可以定义一个函数,该函数将curried函数转换为带有参数的函数:

uncurry f (a, b) = f a b

let calling = someBoolean || (uncurry f) g

答案 2 :(得分:3)

你可以从元组内联中提取,你仍然可以获得短路的好处。

let calling = someBoolean || let a,b = g in f a b

答案 3 :(得分:2)

如前所述,您可以定义uncurry组合器以将带有两个参数的函数转换为带元组的函数。

但是我建议不要这样做 - 这种编程风格在F#中并不是真正的惯用语(不像在Haskell中),我认为它使代码难以阅读,调试和维护。

那么,该怎么做呢?

  • 如果这两个值在逻辑上属于一起(代表代码中其他地方使用的某个实体),那么也要更改f以获取元组。

  • 如果它们只是两个值,则使用let和模式匹配来分解元组。这将更长,但您必须为组件命名,这将提高可读性。

在您的示例中,g实际上是一个值,因此您只需编写:

let someThing, otherThing = g
boolThing || (f someThing otherThing)