関数定義で関数パラメーターのサブタイプを使用できますか?

コリンTバウアーズ

関数定義で関数パラメーターのサブタイプを使用したいと思います。これは可能ですか?たとえば、次のように書きたいと思います。

g{T1, T2<:T1}(x::T1, y::T2) = x + y

したがって、それはのサブタイプであるすべてに対してg定義されます明らかに、たとえば、それが常にであることわかっていれば、私は書くことができ、これはうまくいくでしょう。ただし、この質問は、実行時までわからない場合に使用します。x::T1yT1T1Numberg{T<:Number}(x::Number, y::T) = x + yT1

なぜ私がこれをやりたいのか疑問に思っているなら、読んでください:

私がやろうとしていることの完全な説明は少し面倒ですが、以下は単純化された例です。

パラメータ化されたタイプと、そのタイプに対して定義された単純なメソッドがあります。

type MyVectorType{T}
    x::Vector{T}
end
f1!{T}(m::MyVectorType{T}, xNew::T) = (m.x[1] = xNew)

次のように定義された抽象的なスーパータイプを持つ別のタイプもあります

abstract MyAbstract
type MyType <: MyAbstract ; end

次を使用するようにMyVectorType設定されたベクトル要素タイプのインスタンスを作成しますMyAbstract

m1 = MyVectorType(Array(MyAbstract, 1))

のインスタンスをMyType配置したいと思いますMyVectorType以来、私はこれを行うことができますMyType <: MyAbstractただし、f1!関数定義はxNew、型Tある必要があり、ではなく、にTなることを意味するため、これを行うことはできませMyAbstractMyType

この問題に対して私が考えることができる2つの解決策は次のとおりです。

f2!(m::MyVectorType, xNew) = (m.x[1] = xNew)
f3!{T1, T2}(m::MyVectorType{T1}, xNew::T2) = T2 <: T1 ? (m.x[1] = xNew) : error("Oh dear!")

1つ目は、基本的にダックタイピングソリューションです。2番目は、最初のステップで適切なエラーチェックを実行します。

どちらが好ましいですか?それとも、私が気付いていない3番目のより良い解決策はありますか?

マットB。

関数を定義する機能g{T, S<:T}(::Vector{T}, ::S)は、対角ディスパッチのアナロジーとして「三角ディスパッチ」と呼ばれていますf{T}(::Vector{T}, ::T)(スーパータイプが上と左になるように配置された、行と列にラベルを付けるタイプ階層を持つテーブルを想像してください。行は最初の引数の要素タイプを表し、列は2番目の引数のタイプを表します。斜めのディスパッチはテーブルの対角線に沿ったセルのみに一致しますが、三角形ディスパッチは対角線とその下のすべてに一致し、三角形を形成します。)

これは単にまだ実装されていません これは複雑な問題です。特に、関数定義の範囲内T範囲S外、および不変性のコンテキストで検討を開始すると、問題になります。詳細については、問題#3766および#6984を参照してください。


したがって、実際には、この場合、ダックタイピングは問題ないと思います。の実装に依存して、myVectorType要素を割り当てるときにエラーチェックを実行します。これは、どのような場合でも実行する必要があります。

配列の要素を設定するためのベースジュリアのソリューションは次のようなものです。

f!{T}(A::Vector{T}, x::T) = (A[1] = x)
f!{T}(A::Vector{T}, x) = f!(A, convert(T, x))

タイプ階層やサブタイプ「三角形」については気にしないことに注意してください。それだけで変換しようとxするT...場合は何もしませんいますx::S, S<:Tまたconvert、変換できない場合や方法がわからない場合はエラーが発生します。


更新:これは最新の開発バージョン(0.6-dev)に実装されました!この場合でもconvert、最初に答えたように使用することをお勧めしますが、静的メソッドパラメーター内で左から右の方法で制限を定義できるようになりました。

julia> f!{T1, T2<:T1}(A::Vector{T1}, x::T2) = "success!"

julia> f!(Any[1,2,3], 4.)
"success!"

julia> f!(Integer[1,2,3], 4.)
ERROR: MethodError: no method matching f!(::Array{Integer,1}, ::Float64)
Closest candidates are:
  f!{T1,T2<:T1}(::Array{T1,1}, ::T2<:T1) at REPL[1]:1

julia> f!([1.,2.,3.], 4.)
"success!"

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

Typescript関数パラメーターをブール値または文字列のタイプを持つように定義できますか?

分類Dev

Pythonプログラムで、いくつかのパラメーターを使用してユーザー定義関数を複数回使用できますか?

分類Dev

関数の本体で変数を定義できるのに、なぜ関数でパラメーターを使用するのですか?

分類Dev

Typescriptで関数のパラメーター定義を再利用できますか?

分類Dev

同じ名前でパラメーターが異なる2つの関数を定義できますか?

分類Dev

テンプレート関数のパラメーターのタイプを推測できますか?

分類Dev

関数定義内での位置パラメーターの使用

分類Dev

関数パラメーターのタイプを設定しますか?

分類Dev

関数のパラメーターとしてvoid *を使用できますか?

分類Dev

関数は、その定義内で異なるパラメーターを使用してそれ自体を呼び出すことができますか?

分類Dev

Goで関数のパラメータータイプを設定する

分類Dev

C-関数パラメータリストの多次元配列のサイズを実際のサイズよりも大きく設定できますか?

分類Dev

適用関数内で定義された関数の入力パラメーターを使用する

分類Dev

ループに渡される矢印関数のパラメーターでforループイテレーターを使用できますか?

分類Dev

クラスでプライベート構造を定義するとき、それを関数パラメーターまたは戻り値の型としてどのように使用しますか?

分類Dev

すべての関数パラメーター(同じ数、タイプ、順序)を別の関数に転送できますか?

分類Dev

python角括弧でオプションのパラメータを使用して関数を定義する方法は?

分類Dev

オブジェクトから関数パラメータの継承型を使用できますか?

分類Dev

Obj-c、関数の引数のパラメータのタイプとしてプロトコルを使用できますか?

分類Dev

letを使用して、関数のパラメーターと同じ名前の変数を定義することはできません

分類Dev

Typescript定義と関数呼び出しでパラメーターをオプションにすることはできますか?

分類Dev

Kotlin関数パラメーター:パラメーターとして後続のラムダまたはインターフェイスを持つことができる関数を定義する方法?

分類Dev

「未定義」パラメーターは、関数定義で何を意味しますか

分類Dev

省略記号を使用したフォールバック関数:パラメーターパックのサイズを強制できますか?

分類Dev

名前付きパラメーターで定義された関数のMyPyタイプのヒントですが、** kwargsを取ることができますか?

分類Dev

パラメータと同じデータ型を持つラムダ関数を格納するデータ型を定義できますか?

分類Dev

「タイプ」を関数パラメーターとして渡すことはできますか?

分類Dev

入力タイプにパラメーターを追加する関数のタイプを定義する

分類Dev

「テンプレート関数ポインタ」の型を定義することはできますか?

Related 関連記事

  1. 1

    Typescript関数パラメーターをブール値または文字列のタイプを持つように定義できますか?

  2. 2

    Pythonプログラムで、いくつかのパラメーターを使用してユーザー定義関数を複数回使用できますか?

  3. 3

    関数の本体で変数を定義できるのに、なぜ関数でパラメーターを使用するのですか?

  4. 4

    Typescriptで関数のパラメーター定義を再利用できますか?

  5. 5

    同じ名前でパラメーターが異なる2つの関数を定義できますか?

  6. 6

    テンプレート関数のパラメーターのタイプを推測できますか?

  7. 7

    関数定義内での位置パラメーターの使用

  8. 8

    関数パラメーターのタイプを設定しますか?

  9. 9

    関数のパラメーターとしてvoid *を使用できますか?

  10. 10

    関数は、その定義内で異なるパラメーターを使用してそれ自体を呼び出すことができますか?

  11. 11

    Goで関数のパラメータータイプを設定する

  12. 12

    C-関数パラメータリストの多次元配列のサイズを実際のサイズよりも大きく設定できますか?

  13. 13

    適用関数内で定義された関数の入力パラメーターを使用する

  14. 14

    ループに渡される矢印関数のパラメーターでforループイテレーターを使用できますか?

  15. 15

    クラスでプライベート構造を定義するとき、それを関数パラメーターまたは戻り値の型としてどのように使用しますか?

  16. 16

    すべての関数パラメーター(同じ数、タイプ、順序)を別の関数に転送できますか?

  17. 17

    python角括弧でオプションのパラメータを使用して関数を定義する方法は?

  18. 18

    オブジェクトから関数パラメータの継承型を使用できますか?

  19. 19

    Obj-c、関数の引数のパラメータのタイプとしてプロトコルを使用できますか?

  20. 20

    letを使用して、関数のパラメーターと同じ名前の変数を定義することはできません

  21. 21

    Typescript定義と関数呼び出しでパラメーターをオプションにすることはできますか?

  22. 22

    Kotlin関数パラメーター:パラメーターとして後続のラムダまたはインターフェイスを持つことができる関数を定義する方法?

  23. 23

    「未定義」パラメーターは、関数定義で何を意味しますか

  24. 24

    省略記号を使用したフォールバック関数:パラメーターパックのサイズを強制できますか?

  25. 25

    名前付きパラメーターで定義された関数のMyPyタイプのヒントですが、** kwargsを取ることができますか?

  26. 26

    パラメータと同じデータ型を持つラムダ関数を格納するデータ型を定義できますか?

  27. 27

    「タイプ」を関数パラメーターとして渡すことはできますか?

  28. 28

    入力タイプにパラメーターを追加する関数のタイプを定義する

  29. 29

    「テンプレート関数ポインタ」の型を定義することはできますか?

ホットタグ

アーカイブ