2017-04-05 17 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 

更新

我做了一個包,它提供了基本型支持通過宏觀推論友好泛型函數記憶化。它也允許從函數參數定製緩存鍵。

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

+1

那麼https://github.com/simonster/Memoize.jl呢? –

回答

6

爲了得到朱麗婭專門的執行特定DataType,則必須使用::Type{T}參數類型:

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

這個簡單的變化意味着朱莉婭將專門爲每個和方法每種類型memoize遭遇,而不是隻爲所有DataType s做一個專業化。