Условия на аргументы функции в Julia

В 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.

Спасибо!

Вы, конечно, можете обернуть свои «дополнения» для конкретного диапазона в функцию добавления оболочки, где вы определяете логику, я не думаю (но могу ошибаться), что вы можете сделать это с помощью механизма множественной отправки.

Antonello 16.09.2023 14:38

@Антонелло, спасибо, я искал способ сделать это, как в Mathematica, но да, упаковка подойдет

Nitin 16.09.2023 15:02

Я не думаю, что Mathematica применяет множественную отправку на основе значений. Вы можете написать условный оператор в одну строку, как в Mathematica.

Antonello 16.09.2023 17:38
Что такое компоненты React? Введение в компоненты | Типы компонентов
Что такое компоненты React? Введение в компоненты | Типы компонентов
Компонент - это независимый, многократно используемый фрагмент кода, который делит пользовательский интерфейс на более мелкие части. Например, если мы...
1
3
61
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

В типе вы можете хранить конкретную информацию и использовать ее для отправки. Для примера вы могли бы сделать

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 19.09.2023 03:49

@mcabbott да, это именно моя точка зрения, однако этот ответ соответствует тому, что я спросил, и вполне приемлем как таковой!

Nitin 27.09.2023 17:30

Другие вопросы по теме