2017-04-05 8 views
5
function memoize(f, T) 
    cache = Dict{Any, T}() 
    function g(args...)::T 
     key = make_key(args...) 
     get!(cache, key) do 
      f(args...) 
     end 
    end 
    g 
end 

fib = memoize(x::Int -> begin 
    if x == 2 
     return 2 
    end 
    if x == 1 
     return 1 
    end 
    fib(x - 1) + fib(x - 2) 
end, Int) 

これは私が得るものですが、悲しいことに、私は注釈をつけましたが返信の型は認識しません。型推論型メモ帳を書くには

また、匿名関数の戻り値の型に注釈を付ける方法はありますか?

@code_warntype fib(3) 

Variables: 
    #self#::#g#40{##44#45,DataType,Dict{Any,Int64}} 
    args::Tuple{Int64} 
    key::Tuple{Int64} 
    #39::##39#41{Tuple{Int64},##44#45} 

Body: 
    begin 
     SSAValue(0) = (Core.getfield)(#self#::#g#40{##44#45,DataType,Dict{Any,Int64}},:T)::DataType 
     key::Tuple{Int64} = (Core.tuple)((Core.getfield)(args::Tuple{Int64},1)::Int64)::Tuple{Int64} # line 20: 
     #39::##39#41{Tuple{Int64},##44#45} = $(Expr(:new, ##39#41{Tuple{Int64},##44#45}, :(args), :((Core.getfield)(#self#,:f)::##44#45))) 
     SSAValue(1) = #39::##39#41{Tuple{Int64},##44#45} 
     SSAValue(2) = (Core.getfield)(#self#::#g#40{##44#45,DataType,Dict{Any,Int64}},:cache)::Dict{Any,Int64} 
     return (Core.typeassert)((Base.convert)(SSAValue(0),$(Expr(:invoke, LambdaInfo for get!(::##39#41{Tuple{Int64},##44#45}, ::Dict{Any,Int64}, ::Tuple{Int64}), :(Main.get!), SSAValue(1), SSAValue(2), :(key))))::ANY,SSAValue(0))::ANY 
    end::ANY 

更新

私はマクロ経て型推論優しい汎用関数メモ化のための基本的なサポートを提供し、パッケージを作りました。また、関数の引数からキャッシュキーをカスタマイズすることもできます。特定DataTypeため、その実装を専門とするジュリアを得るために

https://github.com/colinfang/Memoize.jl

+1

https://github.com/simonster/Memoize.jlはどうですか? –

答えて

6

、あなたが::Type{T}パラメトリック・タイプを使用する必要があります。簡単な変更はジュリアがそれぞれの方法を専門とすることを意味することに

function memoize{T}(f, ::Type{T}) 
    … 

をし、すべてDataTypeの1つの特殊化を行う代わりに、すべてのタイプmemoizeが発生します。