# Proper definition of eltype for custom iterator

**URL:** <https://discourse.julialang.org/t/proper-definition-of-eltype-for-custom-iterator/21903>\
**Category:** General Usage\
**Created:** [March 15, 2019, 8:23am UTC](https://discourse.julialang.org/t/proper-definition-of-eltype-for-custom-iterator/21903 "2019-03-15T08:23:19Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![timueh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/timueh/32/12379_2.png) [@timueh](https://discourse.julialang.org/u/timueh)\
**Post date:** [March 15, 2019, 8:23am UTC](https://discourse.julialang.org/t/proper-definition-of-eltype-for-custom-iterator/21903/1 "2019-03-15T08:23:19Z")

</div>

I was looking at the Julia manual and read about [custom iterators](https://docs.julialang.org/en/v1/manual/interfaces/#man-interface-iteration-1). The gist: having defined my own type, once I extend `Base.iterate` + `Base.length` + `Base.eltype` to work with my own type, I can do cool stuff.

Here’s the example from the manual, slightly modified:

```julia
struct Squares
    count::Int
    eltype::DataType
    function Squares(c::Int,e::DataType)
        e <: Real ? new(c,e) : throw(error("only real DataTypes allowed"))
    end
end

Base.iterate(s::Squares, state=1) = state > s.count ? nothing : ( s.eltype(state*state), state+1 )
Base.length(s::Squares) = s.count
Base.eltype(s::Squares) = s.eltype # is this the best way to do this?

```

This let’s me do the following out-of-the-box:

```julia
julia> for i in Squares(4,UInt8) println(i) end
1
4
9
16

julia> collect(Squares(3,Rational{Int64}))
3-element Array{Rational{Int64},1}:
 1//1
 4//1
 9//1

julia> 9 in Squares(3,Float32)
true

```

This is _cool stuff_!

My question is: is `Base.eltype(s::Squares) = s.eltype` the best way to do this? I know the answer is _no_, [quoting from the manual](https://docs.julialang.org/en/v1/base/collections/#Base.eltype):

> The definition `eltype(x) = eltype(typeof(x))` is provided for convenience so that instances can be passed instead of types. However the form that accepts a type argument should be defined for new types.

So what’s the correct syntax for `Base.eltype(::Type{Squares}) = Squares.eltype` (which is clearly incorrect!)?

cheers!

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [March 15, 2019, 8:58am UTC](https://discourse.julialang.org/t/proper-definition-of-eltype-for-custom-iterator/21903/2 "2019-03-15T08:58:36Z")

</div>

I would write it as:

```julia
struct Squares{T <: Real}
    count::Int
end

Base.iterate(s::Squares{T}, state=1) where {T} = state > s.count ? nothing : (T(state^2), state+1)
Base.length(s::Squares) = s.count
Base.eltype(::Type{Squares{T}}) where {T} = T

```

And the code you executed would be written as:

```julia
for i in Squares{UInt8}(4) println(i) end

collect(Squares{Rational{Int64}}(3))

9 in Squares{Float32}(3)

```

---

<div class="post-metadata">

**Author:** ![timueh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/timueh/32/12379_2.png) [@timueh](https://discourse.julialang.org/u/timueh)\
**Post date:** [March 15, 2019, 9:06am UTC](https://discourse.julialang.org/t/proper-definition-of-eltype-for-custom-iterator/21903/3 "2019-03-15T09:06:56Z")

</div>

Cool! This looks good to me. Thansk!
