"""
    AbstractTask

The shared base type for any task.
"""
abstract type AbstractTask end

"""
    AbstractComputeTask <: AbstractTask

The shared base type for any compute task.
"""
abstract type AbstractComputeTask <: AbstractTask end

"""
    AbstractDataTask <: AbstractTask

The shared base type for any data task.
"""
abstract type AbstractDataTask <: AbstractTask end

"""
    DataTask <: AbstractDataTask

Task representing a specific data transfer.
"""
struct DataTask <: AbstractDataTask
    data::Float64
end

"""
    FusedComputeTask{T1 <: AbstractComputeTask, T2 <: AbstractComputeTask} <: AbstractComputeTask

A fused compute task made up of the computation of first `T1` and then `T2`.

Also see: [`get_types`](@ref).
"""
struct FusedComputeTask <: AbstractComputeTask
    first_task::AbstractComputeTask
    second_task::AbstractComputeTask
    # the names of the inputs for T1
    t1_inputs::Vector{Symbol}
    # output name of T1
    t1_output::Symbol
    # t2_inputs doesn't include the output of t1, that's implicit
    t2_inputs::Vector{Symbol}
end
