# How to wrap MetaGraphsNext.MetaDiGraph effectively?

**URL:** <https://discourse.julialang.org/t/how-to-wrap-metagraphsnext-metadigraph-effectively/81718>\
**Category:** New to Julia\
**Created:** [May 26, 2022, 1:40pm UTC](https://discourse.julialang.org/t/how-to-wrap-metagraphsnext-metadigraph-effectively/81718 "2022-05-26T13:40:09Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![seamsay](https://avatars.discourse-cdn.com/v4/letter/s/f475e1/32.png) [@seamsay](https://discourse.julialang.org/u/seamsay)\
**Post date:** [May 26, 2022, 1:40pm UTC](https://discourse.julialang.org/t/how-to-wrap-metagraphsnext-metadigraph-effectively/81718/1 "2022-05-26T13:40:09Z")

</div>

So I need a DAG for a project but I’m really struggling to wrap `MetaDiGraph` in a wrapper struct to ensure that it is in fact a DAG. I eventually gave up and just left it untyped but this has been really bothering ever since, since I’m sure that it must be possible somehow.

I managed to correctly (I assume) define the struct itself

```julia
struct DAG{V, D, _F}
    inner::MetaGraphsNext.MetaDiGraph{Int, V, Graphs.SimpleDiGraph{Int}, D, Nothing, Nothing, _F, Float64}

    function DAG(graph::MetaGraphsNext.MetaDiGraph{Int, V, Graphs.SimpleDiGraph{Int}, D, Nothing, Nothing, _F, Float64}) where {V, D, _F}
        @assert Graphs.is_directed(graph)
        @assert !Graphs.is_cyclic(graph)
        new{V, D, _F}(graph)
    end
end

```

which works fine when used like this

```julia
julia> DAG(MetaGraphsNext.MetaGraph(Graphs.DiGraph(), Label = String, VertexData = Symbol))
DAG{String, Symbol, MetaGraphsNext.var"#3#5"}(Meta graph based on a {0, 0} directed simple Int64 graph with vertex labels of type String, vertex metadata of type Symbol, edge metadata of type Nothing, graph metadata given by nothing, and default weight 1.0)

```

but from there I’m running into two problems.

The first one is that I want to define a zero-argument constructor that I can use to avoid having to specify the full `MetaGraph` constructor each time. I tried this in a few different ways but the two that _felt_ closest to being correct were

```julia
DAG(::Type{V}, ::Type{D}) where {V, D} = let f = x -> 1.0
    DAG{V, D, typeof(f)}(MetaGraphsNext.MetaGraph(Graphs.DiGraph(), Label = V, VertexData = D, weight_function = f))
end

```

and:

```julia
DAG(V}, ::Type{D}) where {V, D} = let f = x -> 1.0
    DAG{V, D, typeof(f)}(MetaGraphsNext.MetaGraph(Graphs.DiGraph(), Label = V, VertexData = D, weight_function = f))
end

```

Unfortunately neither of these work…

```julia
julia> DAG(String, Symbol)
ERROR: MethodError: no method matching DAG{String, Symbol, var"#1#2"}(::MetaGraphsNext.MetaDiGraph{Int64, String, Graphs.SimpleGraphs.SimpleDiGraph{Int64}, Symbol, Nothing, Nothing, var"#1#2", Float64})
Stacktrace:
 [1] DAG(#unused#::Type{String}, #unused#::Type{Symbol})
   @ Main ~/a/path/to/project/dag.jl:33
 [2] top-level scope
   @ REPL[1]:1

julia> DAG{String, Symbol}()
ERROR: MethodError: no method matching DAG{String, Symbol, var"#1#2"}(::MetaGraphsNext.MetaDiGraph{Int64, String, Graphs.SimpleGraphs.SimpleDiGraph{Int64}, Symbol, Nothing, Nothing, var"#1#2", Float64})
Stacktrace:
 [1] (DAG{String, Symbol})()
   @ Main ~/a/path/to/project/dag.jl:33
 [2] top-level scope
   @ REPL[1]:1

```

The other problem that I’m facing is that I can’t create a type alias for `DAG` to avoid having to specify the types each time. Normally I’d do something like this

```julia
const SpecificDAG = DAG{String, Symbol}

```

but if I do that then I can’t build the type anymore

```julia
julia> StringSymbolDAG(MetaGraphsNext.MetaGraph(Graphs.DiGraph(), Label = String, VertexData = Symbol))
ERROR: MethodError: no method matching (StringSymbolDAG)(::MetaGraphsNext.MetaDiGraph{Int64, String, Graphs.SimpleGraphs.SimpleDiGraph{Int64}, Symbol, Nothing, Nothing, MetaGraphsNext.var"#3#5", Float64})
Stacktrace:
 [1] top-level scope
   @ REPL[2]:1

```

which is not what happens if I do a similar thing for `Dict` (as an example)

```julia
julia> const SpecificDict = Dict{String, Symbol}
Dict{String, Symbol}

julia> SpecificDict()
Dict{String, Symbol}()

julia> SpecificDict("a" => :a)
Dict{String, Symbol} with 1 entry:
  "a" => :a

```

I feel like there’s just something about parametric types that I just don’t understand, but one step at a time I guess. Can anyone help me out here?
