By the way, this overly verbose syntax is a great excuse to write a macro:
using MacroTools
using FunctionWrappers: FunctionWrapper
wrapperize(x) = esc(x)
function wrapperize(expr::Expr)
if expr.head == :block
return Expr(:block, wrapperize.(expr.args)...)
elseif expr.head == :tuple
return Expr(:tuple, wrapperize.(expr.args)...)
elseif @capture(expr, (inputs__,) -> output_)
return :(FunctionWrapper{$(wrapperize(output)), Tuple{$(wrapperize.(inputs)...)}})
elseif @capture(expr, (input_) -> output_)
return :(FunctionWrapper{$(wrapperize(output)), Tuple{$(wrapperize(input))}})
else
error("I can only handle expressions of the form `(inputs...) -> output`")
end
end
macro fn(expr)
wrapperize(expr)
end
Examples:
julia> @fn Int -> Int
FunctionWrapper{Int64, Tuple{Int64}}
julia> @fn (Int, Float64) -> Int
FunctionWrapper{Int64, Tuple{Int64, Float64}}
julia> @fn (Float64, Int -> Int) -> String
FunctionWrapper{String, Tuple{Float64, FunctionWrapper{Int64, Tuple{Int64}}}}