Julia 0.5 の変更ログによると、
各関数とクロージャーには独自の型があります。
これは、より詳細な情報を高次関数に提供できるようになったことを意味しますfoo(bar :: Function{Float64}) = ...
か?bar
Function
もしそうなら、そうする正しい方法は何ですか?そうでない場合、コンパイラが生成されたコードをより適切に最適化できる以外に、この変更の実際のインポートは何ですか? ティア。
Julia 0.5 の変更ログによると、
各関数とクロージャーには独自の型があります。
これは、より詳細な情報を高次関数に提供できるようになったことを意味しますfoo(bar :: Function{Float64}) = ...
か?bar
Function
もしそうなら、そうする正しい方法は何ですか?そうでない場合、コンパイラが生成されたコードをより適切に最適化できる以外に、この変更の実際のインポートは何ですか? ティア。
いいえ、そうではありません。私はあなたが何を得ているかを見て、それが好きですが、それは不可能です. (確かに現在ではありません。おそらく今後もありません。いつか特性を使用するかもしれません。)
例を見てみましょうfoo
:bar
julia> foo(x::String) = println(x)
foo (generic function with 1 method)
julia> foo(x::Int64) = println(x+1)
foo (generic function with 2 methods)
julia> bar(x...) = println(x)
bar (generic function with 1 method)
型階層とは何foo
ですか?
julia> typeof(foo)
#foo
julia> supertype(typeof(foo))
Function
julia> supertype(supertype(typeof(foo)))
Any
foo
したがって、関数の型#foo
は のサブタイプである であることがわかりますFunction
。これは生成された名前であることを意味することに注意してください#
。コードを書くだけではハッシュを名前に入れることはできませんが、ジュリアコンパイラー(用語を大まかに使用)はできます。
そのスーパースーパータイプが機能だけでなく、より具体的でないのはなぜですか?
それはどうなりますか?Function{Int64}
またはFunction{String}
?
juliaの関数には型シグネチャがありませんが、メソッドにはあります。
関数は複数のディスパッチの単なる名前であり、メソッドは実際にディスパッチされるものです。大まかに言えば、関数名はどのテーブルを調べる必要があるかを示しており、引数の型 (つまり、型シグネチャ) がそのテーブルで検索するための鍵です。そのキーを使用して、メソッド自体が返されます。
それでは、例を続けて、何ができるか見てみましょう。
julia> dothing(f::typeof(foo)) = f(rand([randstring(), rand(Int64)]))
dothing (generic function with 1 method)
julia> dothing(foo)
3139374763834167054
julia> dothing(foo)
Ed2kNGrd
julia> dothing(bar)
ERROR: MethodError: no method matching dothing(::#bar)
Closest candidates are:
dothing(::#foo) at REPL[11]:1
dothing
したがって、引数としてa のみを取るように を制限すること#foo
に成功しました。を与えるとエラーがスローされることを確認してください#bar
。foo
関数は type の唯一のものであるため、これはあまり役に立ちません#foo
。
Union
ただし、次のように使用できます。
julia> dootherthing(f::Union{typeof(foo),typeof(bar)}) = f(rand([randstring(), rand(Int64)]))
dootherthing (generic function with 1 method)
julia> dootherthing(foo)
9107791406050657562
julia> dootherthing(foo)
SmB2Xmw8
julia> dootherthing(bar)
("1IpZIMnx",)
julia> dootherthing(bar)
(-6356894350805213697,)
julia> dootherthing(str)
ERROR: UndefVarError: str not defined
julia> dootherthing(string)
ERROR: MethodError: no method matching dootherthing(::Base.#string)
Closest candidates are:
dootherthing(::Union{#bar,#foo}) at REPL[19]:1
dootherthing
#foo
またはを受け入れます#bar
。どちらの機能も動作します。
これは、ホワイトリストとして、用途が限られています。