# How can I get this to infer types?

**URL:** <https://discourse.julialang.org/t/how-can-i-get-this-to-infer-types/33617>\
**Category:** General Usage\
**Created:** [January 21, 2020, 12:15pm UTC](https://discourse.julialang.org/t/how-can-i-get-this-to-infer-types/33617 "2020-01-21T12:15:16Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)\
**Post date:** [January 21, 2020, 12:15pm UTC](https://discourse.julialang.org/t/how-can-i-get-this-to-infer-types/33617/1 "2020-01-21T12:15:16Z")

</div>

I’m having problems getting my code to infer a return type correctly. Here’s a MWE:

```julia
using Test
struct TwoTo{N} end
@inline t(g::Base.Generator{<:TwoTo{N}, F}) where {N,F} = ntuple(i->g.f(i+1), Val{N-1}())
f(r) = t(t(i for i in r) for j in r)
Test.@inferred f(TwoTo{3}())
# ERROR: return type Tuple{Tuple{Int64,Int64},Tuple{Int64,Int64}} does not match inferred return type Tuple{Tuple{Any,Any},Tuple{Any,Any}}

```

If I change the definition of `t` to:

```julia
@inline t(g::Base.Generator{<:TwoTo{N}, F}) where {N,F} = ntuple(g.f, Val{N-1}())

```

then type inference works (but the output is different, of course.)

I can’t figure out any way to wrap `g.f` in a function in a way that does not destroy type inference. Any help would be appreciated!

---

<div class="post-metadata">

**Author:** ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)\
**Post date:** [January 21, 2020, 2:31pm UTC](https://discourse.julialang.org/t/how-can-i-get-this-to-infer-types/33617/2 "2020-01-21T14:31:36Z")

</div>

I think I’ve figured this out. If I change the code slightly:

```julia
using Test
struct TwoTo{N} end
@inline t(g::Base.Generator{<:TwoTo{N}, F}) where {N,F} = ntuple(i->g.f(i+1), Val{N-1}())
@inline u(g::Base.Generator{<:TwoTo{N}, F}) where {N,F} = ntuple(i->g.f(i+1), Val{N-1}())
f2(r) = t(u(i for i in r) for j in r)
Test.@inferred f2(TwoTo{3}())

```

then it works. (Note that `u` is an exact copy of `t`, only with a different name.)  
Apparently, type inference gives up when `t` calls itself recursively even though the function argument is different. I can see how this can be a reasonable heuristic. Now I just need to figure out a good way to get around it!
