目前,我在其中一个函数中使用了类似的方法:(所有变量都与更复杂的函数一起使用,但是对于我要问的问题来说,这无关紧要,并且我会简化)
fun RecursiveCall (p, q, r, s) =
let
val (ra, rb, rc) = returnResult (p, q, s)
in
RecursiveCall (p, ra, rb, rc)
end
我该如何用一种更短(更好)的方式编写代码?意思是,如何提取从函数返回的元组的元素,并将其作为另一个元组的参数传递?
注意:也可以简单地写RecursiveCall (p, #1 (returnResult (p, q, s)) , #2 (returnResult (p, q, s)), #3 (returnResult (p, q, s)))
,但是(可能)在某些情况下,这会使同一件事运行3次,即returnResult。
答案 0 :(得分:1)
在不了解您的实际问题的情况下很难说出任何常规的东西,但是您可以将元组的最后三个元素组合在一起(看起来像是一个单元),例如
fun RecursiveCall p (q, r, s) = RecursiveCall p (returnResult (p, q, s))
答案 1 :(得分:0)
(p, #1 (returnResult (p, q, s)), #2 (returnResult (p, q, s)), #3 (returnResult (p, q, s)))
这会 [...] 使同一件事运行三遍
是的,没错。而且它也比您最初的建议更为冗长。
您也可以写例如
case returnResult (p, q, s) of
(ra, rb, rc) => recursiveCall (p, ra, rb, rc)
替代“让步”。
您可以使用returnResult
和recursiveCall
curried函数并使用uncurry3
:
fun curry3 f x y z = f (x, y, z)
fun uncurry3 f (x, y, z) = f x y z
fun returnResult p q s = (p + 1, q + 2, s + 3)
fun recursiveCall p q r s =
uncurry3 (recursiveCall p) (returnResult p q s)
这里,recursiveCall p
部分应用于其四个参数之一,从而使其成为接受三个咖喱参数的函数。 uncurry3 (recursiveCall p)
因此成为接受三元组的函数,这是returnResult p q s
的精确结果。
此方法依赖于方便地组合在一起的参数顺序。
但是我认为这是returnResult
返回太多东西的征兆。
理想情况下,函数返回其名称表明它可以计算的一件事。
也许returnResult
所做的某些计算可以分解为多个函数,或者也许它们确实是一回事,应该包装在一个通用的数据类型中,或者也许p
,{{ 1}}和q
最好作为阅读器/状态单子的隐式参数传递。对于当前的ML,我没有一个很好的例子,但是由于代码是假设的,因此我也无法说清情况是什么。