Specify the type of function when it is a parameter of another function

Perhaps the question doesn’t matter much in practice or even makes little sense in theory. In which case, please explain the reasons in a simple way.
Playing with the splitarray function, I wondered if and how it was possible to impose constraints on the dlm function.
In particular, the fact that it must have elements of type T in input and a Boolean value in output.

function splitarray(a:: Vector{T},dlm::Function) where T
    spl=findall(dlm,a)
    getindex.([a], (:).([1; spl.+ 1], [spl.- 1; lastindex(a)]))
end

I don’t think so. A function’s type is typeof(functionname), and that is a direct subtype of Function.

julia> typeof(sin) |> supertypes
(typeof(sin), Function, Any)

So there’s no place in the type hierarchy that specifies its input or output types.

Within your function, you can do a hasmethod check if needed, but generally you’ll get a MethodError if the function can’t accept the right types anyway, so that’s usually unnecessary.

1 Like

What are you trying to accomplish? Do you wish to dispatch on properties of the function? Or just check whether the function has the right signature before calling findall?

Just this^ check.

As I said it is just an exercise to experiment with various language features.
I was wondering if it was possible to filter the input parameters without making explicit checks within the function.
But, if I am not mistaken, in fact dlm is the same predicate that is used as a parameter by findall and, as far as I can understand / see, it does not make these restrictions.

PS
however, I would be curious to know if, even with some unorthodox artifice, it is possible to impose these restrictions.
For example by defining a new structure that contains only functions with those characteristics.

You could use a functor.

# Define abstract type for the class of functions deemed acceptable.
abstract type MyFunction{T} <: Function end

# Functor
struct F1{T} <: MyFunction{T}
    x :: T
end

function (f :: F1{T})(z :: T) where T
    f.x + z;
end

fct1 = F1(1.0);

@assert fct1 isa MyFunction{Float64};

@assert fct1(2.0) ≈ 3.0

function bar(f :: MyFunction{T}, z :: AbstractVector{T}) where T
    findall(y -> y < f.x, z)
end

@show bar(fct1, [0.5, 0.7, 1.2, 2.3])
1 Like