Parametrized function type?

Is it possible to specify the signature of a function?

# mycall : (A -> B) -> A -> B
mycall(f::Function{A,B}, a::A)::B where {A,B} = f(a)
ERROR: UndefVarError: A not defined

TLDR is no. Every function in Julia has it’s own type. The simple reason for this is that functions do not have specific input or output types. Consider + what are it’s input and output types?

1 Like

I’d say, it’s an inductive type Has{+}, just like an extensible enum.

Julia doesn’t have inductive types (or dependent types for that matter).

I tried to find a workaround. Why didn’t this work?

julia> f(x::Float64)::Float64 = 1.0
f (generic function with 1 method)

julia> let T = typeof(f); methods(T.instance).ms[1].sig.types[2] == Core.Compiler.return_type(T.instance, (methods(T.instance).ms[1].sig.types[2],)) end
true

# mycall : (A -> B) -> A -> B
julia> mycall(f::T,a::A) where {methods(T.instance).ms[1].sig.types[2] == Core.Compiler.return_type(T.instance, (methods(T.instance).ms[1].sig.types[2],)), A}  = f(a)
ERROR: syntax: invalid variable expression in "where" around REPL[15]:1

EDIT: I think function calls aren’t allowed in where expressions.

mycall(f::T,a::A) where {g(T),A} = f(a)
ERROR: syntax: invalid variable expression in "where" around REPL[20]:1

Aren’t functors useful there?

julia> struct F{A}
       end

julia> (f::F)(x) = sin(x)

julia> mycall(f::F{A}, a::A) where {A} = f(a)
mycall (generic function with 1 method)

julia> f = F{Int}()
F{Int64}()

julia> mycall(f,1)
0.8414709848078965

julia> mycall(f,1.0)
ERROR: MethodError: no method matching mycall(::F{Int64}, ::Float64)

I am not sure if there is something that can be done with the return value, as you seem to try in the example.

1 Like