Function as Type Parameter

Thank you, this exactly what I need. Here’s the final code for future reference:

# Quick implementation of a lazy Array. Yes, it's really *that* simple.
mutable struct LazyFunctionArray{F<:Function,T,N} <: AbstractArray{T,N}
    const f::F                   # Julia 1.8 const field syntax for convenience
    const size::NTuple{N,Int}
    ncalls::Int
end
const LazyFunctionVector{F,T} = LazyFunctionArray{F,T,1}
const LazyFunctionMatrix{F,T} = LazyFunctionArray{F,T,2}


function LazyFunctionArray(T::Type, f::F, dims::Vararg{Int,N}) where {F<:Function,N}
    LazyFunctionArray{F,T,N}(f, dims, 0)
end

function LazyFunctionArray(f::F, dims::Vararg{Int,N}) where {F<:Function,N}
    LazyFunctionArray(Float64, f, dims...)
end

function LazyFunctionVector(T::Type, f::F, n::Int) where {F<:Function}
    LazyFunctionVector{T,F}(f, (n,), 0)
end

function LazyFunctionVector(f::F, n::Int) where {F<:Function}
    LazyFunctionVector(Float64, f, n)
end

function LazyFunctionMatrix(T::Type, f::F, n::Int, m::Int) where {F<:Function}
    LazyFunctionMatrix{F,T}(f, (n, m), 0)
end

function LazyFunctionMatrix(f::F, n::Int, m::Int) where {F<:Function}
    LazyFunctionMatrix(Float64, f, n, m)
end

function Base.size(A::LazyFunctionArray)
    A.size
end

function Base.getindex(A::LazyFunctionArray{F,T,1,}, i::Int) where {F<:Function,T}
    A.ncalls += 1
    A.f(i)
end

function Base.getindex(A::LazyFunctionArray{F,T,N}, I::Vararg{Int,N}) where {F<:Function,T,N}
    A.ncalls += 1
    A.f(I...)
end

function benchmark_eval()
    A = LazyFunctionArray((x, y) -> x + y, 1000, 1000)
    m = Matrix(A)
    @benchmark m = Matrix($A)
end

benchmark_eval()