В Julia можно указать тип аргумента для функции, например: addition(x::Int64,y::Int64)
. Я могу одновременно определить еще одну функцию с тем же именем: addition(x::Float64,y::Int64)
Можно ли также указать вышеуказанную функцию так, чтобы вместо ограничения типа я указал ограничение на значения, которые x
или y
могут принимать? Так, например, я мог бы сказать, что если x
принимает значения от 1,0 до 15,0, то используйте одно определение addition
, а если оно принимает значения выше 15,0, тогда используйте другое определение.
Итак, по сути, я хотел бы указать диапазон значений, которые могут принимать аргументы функции, как это можно сделать в Mathematica: addition[i_, j_] /; 0.0 <= i <= 15.0 && 0.0 <= j <= 15.0 := i + j
.
Спасибо!
@Антонелло, спасибо, я искал способ сделать это, как в Mathematica, но да, упаковка подойдет
Я не думаю, что Mathematica применяет множественную отправку на основе значений. Вы можете написать условный оператор в одну строку, как в Mathematica.
В типе вы можете хранить конкретную информацию и использовать ее для отправки. Для примера вы могли бы сделать
struct ValT{T}
x::Float64
end
У вас могут быть следующие объекты:
a=ValT{:small}(3)
b=ValT{:big}(100)
И вы можете отправить соответственно:
f(u::ValT{:big}) = u.x + 1000;
f(u::ValT{:small}) = u.x + 10;
Единственная проблема заключается в том, что значения известны во время выполнения, а не во время компиляции, и создаваемая функция ValT{}
не будет стабильной по типу.
Учитывать:
value(x) = ValT{x < 5 ? :small : :big}(x)
Эту функцию можно использовать для удобного создания объекта соответствующего типа для ваших нужд.
julia> value(4)
ValT{:small}(4.0)
julia> value(40)
ValT{:big}(40.0)
Однако есть небольшая проблема: функция value
, создающая ValT
, не является стабильной по типу и не может быть эффективно скомпилирована:
Это может быть проблемой или нет, в зависимости от конкретного сценария использования, но в принципе этого следует избегать.
В том, что здесь делает Mathematica, нет ничего особенного, это умеет каждый язык программирования в истории, и Julia тоже.
addition[i_, j_] /; 0.0 <= i <= 15.0 && 0.0 <= j <= 15.0 := i + j
становится
addition(i, j) = (0<=i<=15) && (0<=i<=15) && return i+j
Но что должна делать функция, если входные данные не попадают в диапазоны? Прямо сейчас оно вернется nothing
.
Может быть false
скорее. Но то, что здесь делает Mathematica, (я думаю) немного другое. /;
прикрепляет это определение условно, но можно прикрепить и более поздние определения, причем всегда используется наиболее конкретное совпадающее. Это похоже на отправку Джулии, где вы всегда можете добавить больше методов. Но он допускает значения, а не только типы — язык более динамичен, в нем нет понятия времени компиляции. (Их помощь: reference.wolfram.com/language/ref/Condition.html )
@mcabbott да, это именно моя точка зрения, однако этот ответ соответствует тому, что я спросил, и вполне приемлем как таковой!
Вы, конечно, можете обернуть свои «дополнения» для конкретного диапазона в функцию добавления оболочки, где вы определяете логику, я не думаю (но могу ошибаться), что вы можете сделать это с помощью механизма множественной отправки.