在SML中重新定位元组元素的更短方法

问题描述 投票:0回答:2

目前,我在我的一个函数中使用了这样的东西:(所有变量都用于更复杂的函数,但是对于我将要求它并不重要而且我简化了)

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)))但是(可能)这会在某些情况下导致同样的事情运行三次,即returnResult。

sml smlnj
2个回答
1
投票

没有关于你的实际问题的知识就很难说一般,但是你可以将元组的最后三个元素组合在一起(看起来它们是一个单元),就像

fun RecursiveCall p (q, r, s) = RecursiveCall p (returnResult (p, q, s))

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)

作为let-in-end的替代方案。

你可以制作returnResultrecursiveCall 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部分应用于其四个参数中的一个,使其成为一个接受三个curried参数的函数。因此,uncurry3 (recursiveCall p)成为一个接受三元组的函数,这是returnResult p q s的精确结果。

这种方法依赖于方便地拟合在一起的参数的顺序。

但我认为这是returnResult返回太多东西的症状。

理想情况下,函数返回他们的名字暗示它计算的一件事。

也许returnResult所做的一些计算可以分成多个函数,或者它们可能只是一个东西,应该包含在一个公共数据类型中,或者pqs最好作为读者的隐含参数传递/州monad。我没有一个很好的例子,说明手头的最后一件事情如何,但我也不能说情况需要什么,因为代码是假设的。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.