Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass a function typesafe in julia

Let's say, I want to pass a function to another function:

function foo()
    return 0;
end
function bar(func)
    return func();
end
print(bar(foo));

But you can make functions typesafe:

function func(t::Int)
    print(t);
end
func(0);                 #produces no error
func("Hello world");     #produces an error

I didn't found out, how I combine both, that means, how can I explicitly define a parameter of bar, like func, to be a function, possibly with certain input / output argument types.

Thanks in advance for any help.

like image 371
GuiTaek Avatar asked Dec 18 '19 12:12

GuiTaek


1 Answers

If I understand you correctly you want to make sure the passed function returns a specific type? The simplest thing is to just typeassert the return value at runtime:

julia> function f(func)
           val = func()::Int # Error if the return value is not of type Int
           return val
       end
f (generic function with 1 method)

julia> f(() -> 1)
1

julia> f(() -> 1.0)
ERROR: TypeError: in typeassert, expected Int64, got Float64
Stacktrace:
 [1] f(::var"#7#8") at ./REPL[5]:2
 [2] top-level scope at REPL[8]:1

Alternatively you can use the FunctionWrappers.jl package (which will convert to the specified return type, or error if the conversion is not possible):

julia> using FunctionWrappers: FunctionWrapper

julia> function f(func::FunctionWrapper{Int,<:Tuple})
           val = func()
           return val
       end;

julia> function f(func)
           fw = FunctionWrapper{Int,Tuple{}}(func)
           return f(fw)
       end;

julia> f(() -> 1)
1

julia> f(() -> 1.0) # Can convert to Int
1

julia> f(() -> 1.2) # Can not convert to Int
ERROR: InexactError: Int64(1.2)
like image 54
fredrikekre Avatar answered Sep 23 '22 04:09

fredrikekre