Как я могу аннотировать число как тип в параметрическом типе

Я новичок в Юлии.

Мне было любопытно узнать тип значения в julia, поэтому я тестирую их несколько.

using StaticArrays
struct MT{N,Np1}
    x::SVector{N,Int}
    y::SVector{Np1,Int}
    function MT(x::SVector{T,Int},y::SVector{V,Int}) where {T, V}
        Val{T}() == Val{V}() || throw(ArgumentError("mismatched lengths; y must be one element longer than x"))
        new{T, V}(x,y)
    end
end

MT(SVector{3,Int}(1,2,3),SVector{3,Int}(1,2,3))

Мой вопрос таков:

  1. Могу ли я аннотировать тип T и V в предложении where? (Например, «где {T=Int, V=Int}» или что-то в этом роде?)
  2. Можем ли мы ограничить тип T как Integer, используя аннотацию типа? (Разрешить MT{1,1}, но не MT{1.0, 1.0})

Мне нужен рабочий код с аннотацией типа.

Как создавать пользовательские общие типы в Python (50/100 дней Python)
Как создавать пользовательские общие типы в Python (50/100 дней Python)
Помимо встроенных типов, модуль типизации в Python предоставляет возможность определения общих типов, что позволяет вам определять типы, которые могут...
0
0
72
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

struct MT{N,Np1}
    x::SVector{N,Int}
    y::SVector{Np1,Int}
    function MT(x::SVector{T,Int},y::SVector{V,Int}) where T <: Integer where V <: Int
        Val{T}() == Val{V}() || throw(ArgumentError("mismatched lengths; y must be one element longer than x"))
        new{T, V}(x,y)
    end
end

делает то, что вы просите (он просто заменяет where {T, V} в вашем коде на where T <: Integer where V <: Int. См. документацию для where для получения дополнительной информации.

Есть несколько вопросов, которые я рассмотрел по поводу вашего вопроса. SVector{S, T} может иметь тип T, различающийся по типу, но S является числом элементов и, насколько мне известно, должен быть Int. Таким образом, пакет SVector должен обеспечить для вас тип S. Таким образом, where обычно используется для изменения второго типа в SVector, который вы всегда устанавливаете здесь как Int.

После вашего определения MT выполнение «MT (SVector {3, Int} (1,2, 3), SVector {3, Int} (1, 2, 3))» дает мне ошибку (тем не менее, код, который я написал, работающий). Мои фокусы были на T и V. Я думал, что T и V просто работают, как концепция, называемая const generic в ржавчине, поэтому она будет иметь аннотацию типа. (например: ограничить тип T как Integer). Является ли S в SVector {S, T} просто числом, а не типом, поэтому оно находится в общем параметре?

하현욱 13.02.2023 08:26

Этот ответ не подойдет, так как 3 не является подтипом Integer. Отношение между 3 и Integer является isa-отношением, а не <:-отношением.

DNF 13.02.2023 09:09

Я думаю, что, поскольку where() требует типов в качестве аргументов, и ваша проблема заключается в том, что вы хотите воздействовать на значение целого числа, а не на целое число, я бы не стал использовать свой ответ, а вместо этого использовал что-то вроде if Val(V) - T != 1 в тело функции и вообще не указывать T с where.

Bill 13.02.2023 19:40
Ответ принят как подходящий

Ответ на ваш вопрос об ограничении типа параметров T и V заключается в том, что вы не можете сделать это для параметров, отличных от типа/значения. Было бы неплохо, но нельзя.

Только отношения подтипа могут быть применены к параметрам типа, а параметры-значения не могут быть в отношениях подтипа:

julia> 3 isa Integer  # this is a valid relationship
true

julia> 3 <: Integer  # this is not
ERROR: TypeError: in <:, expected Type, got a value of type Int64

Вместо этого гипотетический синтаксис может быть where {T::Int, V::Int} или where {T isa Int, V isa Int}. Я не знаю, почему это невозможно, но это общеизвестное ограничение.

Кстати: вы можете просто написать T == V. Не надо Val{T}() == Val{V}(). Вычисление происходит во время компиляции, так как оба являются параметрами типа.

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