Enforcing function signatures by both argument & return types

It’s becoming a bit complicated but I think this works:

Now you can provide the signature you want to the constructor and it look through the function’s methods to find a match (returns an error otherwise)


f(z,x::Int,y::Int) = x+z
f(x::Int,y::Float64) = x+y
f(x::Int) = x
f() = 2

julia> tf1 = TypedFunction(f, (Int,Float64),(Float64))
f: Tuple{Int64,Float64} → Float64

You can use dispatch to put constrains on input/output types:

g(f::TypedFunction{T,I,O}) where {T,I<:Tuple{Number,Float64},O<:Number} = 1

julia> g(tf1)
1

Or use the function match_signature to check if there’s a method matching the signature:

match_signature(f,(Float64,Int,Int),(Float64),false)

The last argument determine if strict check is done (==) or subtyping (<:) which makes generic functions work too:

julia> match_signature(f,(Float64,Int,Int),(Float64),false)
1-element Array{Any,1}:
 f(z, x::Int64, y::Int64) 

There’s probably some issues I haven’t thought about.

3 Likes