(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
curry функциями и использовать 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)
становится функцией, которая принимает 3-кортеж, что является точным результатом returnResult p q s
.
Этот метод опирается на порядок аргументов, удобно сочетающихся друг с другом.
Но я думаю, что это признак returnResult
возврата слишком многих вещей.
В идеале функции возвращают одну вещь, которую их имя предполагает, что она вычисляет.
Возможно, некоторые из вычислений, которые выполняет returnResult
, можно разделить на несколько функций, или, может быть, они действительно едины и должны быть заключены в общий тип данных, или, возможно, p
, q
и s
лучше передавать как неявные аргументы читателя / монады состояния. У меня нет хорошего примера того, как выглядит последняя вещь в ML, но я также не могу сказать, что требует ситуация, так как код является гипотетическим.