# Specification of the signature of a Function in a struct

Hi. I’ve got a struct that has a Function as a field. I’d like to specify the signature of this function in some way, for example:

``````struct Mapper
lower::Float64
upper::Float64
mapFunc::Function{Float64 -> Float64}
end
``````

Is there any way of doing this?
Thanks.

Depends on what you want to do with it, but generally not. If you are interested in the rationale and alternative solutions, search the discussions for “arrow types”.

If you just want concrete types, the idiomatic solution is

``````struct Mapper{T}
lower::Float64
upper::Float64
mapFunc::T
end
``````

Thanks! I’ll look into arrow types, as you suggest.

Could a possible solution be to define a struct and a functor

``````struct TypedFunction{F<:Function, Tin, Tout}
f::F
end

TypedFunction(f::F, ::Type{Tin}, ::Type{Tout}) where {F, Tin, Tout} = TypedFunction{F, Tin, Tout}(f)

function (typedfun::TypedFunction{F, Tin, Tout})(x::Tin) where {F, Tin, Tout}

return convert(Tout, typedfun.f(x))

end
``````

where `Tin` is the type of the input and `Tout` the type of the output and the functor guarantees that the input and the output are of the correct type.

In this way, if I define

`mysin = TypedFunction(sin, Float64, Float64)`

the compiler always know `mysin` only accepts arguments of the type `Float64` and the returned value of `mysin(2.0)` is always a `Float64`. Correct?

P.S:: This discussion is related to this problem: Enforcing function signatures by both argument & return types

Actually, it does not.

For direct use, it works:

``````julia> @code_warntype(mysin(1.5))
Variables
typedfun::Core.Compiler.Const(TypedFunction{typeof(sin),Float64,Float64}(sin), false)
x::Float64

Body::Float64
1 ─ %1 = \$(Expr(:static_parameter, 3))::Core.Compiler.Const(Float64, false)
│   %2 = Base.getproperty(typedfun, :f)::Core.Compiler.Const(sin, false)
│   %3 = (%2)(x)::Float64
│   %4 = Main.convert(%1, %3)::Float64
└──      return %4
``````

`sin` works for indirect use:

``````
julia> function testsin(x::Float64)
y = sin(x)
return y
end
testsin (generic function with 1 method)

julia> @code_warntype(testsin(0.5))
Variables
#self#::Core.Compiler.Const(testsin, false)
x::Float64
y::Float64

Body::Float64
1 ─     (y = Main.sin(x))
└──     return y
``````

here is `mysin`

``````
julia> function testmysin(x::Float64)
y = mysin(x)
return y
end
testmysin (generic function with 1 method)

julia> @code_warntype(testmysin(0.5))
Variables
#self#::Core.Compiler.Const(testmysin, false)
x::Float64
y::Any

Body::Any
1 ─     (y = Main.mysin(x))
└──     return y
``````

Thanks for the feedback! That is interesting. But if I declare `mysin` as a `const`

``````const mysin = TypedFunction(sin, Float64, Float64)

function testmysin(x::Float64)
y = mysin(x)
return y
end
``````

then it seems to work fine

``````julia> @code_warntype(testmysin(0.5))
Body::Float64
1 ─ %1 = invoke sin(_2::Float64)::Float64
└──      return %1
``````

I am not sure I understand why it works in this case…

const values propagate well