# Imap (from IterTools.jl) doesn't preserve type

**URL:** https://discourse.julialang.org/t/imap-from-itertools-jl-doesnt-preserve-type/7683
**Category:** General Usage
**Tags:** question
**Created:** [December 10, 2017, 9:20pm UTC](https://discourse.julialang.org/t/imap-from-itertools-jl-doesnt-preserve-type/7683 "2017-12-10T21:20:15Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![scelles](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scelles/32/220408_2.png) [@scelles](https://discourse.julialang.org/u/scelles)
#### Post date: [December 10, 2017, 9:20pm UTC](https://discourse.julialang.org/t/imap-from-itertools-jl-doesnt-preserve-type/7683/1 "2017-12-10T21:20:15Z")

</div>

Hello,

I don’t really know if that a bug or a limitation but `imap` from [IterTools.jl](https://github.com/JuliaCollections/IterTools.jl) doesn’t preserve type

```julia
julia> itr = imap(x->2*x, 1:10)
julia> collect(itr)
10-element Array{Any,1}:
  2
  4
  6
  8
 10
 12
 14
 16
 18
 20

```

I was expecting same result (ie Vector of Int) as

```julia
julia> 2*collect(1:10)
10-element Array{Int64,1}:
  2
  4
  6
  8
 10
 12
 14
 16
 18
 20

```

or

```julia
julia> map(x->2*x, 1:10)
10-element Array{Int64,1}:
  2
  4
  6
  8
 10
 12
 14
 16
 18
 20

```

My goal is to simply apply a function to values of an iterator and get a new iterator (preserving type)

Kind regards

---

<div class="post-metadata">

### Author: ![bicycle1885](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bicycle1885/32/107_2.png) [@bicycle1885](https://discourse.julialang.org/u/bicycle1885)
#### Post date: [December 11, 2017, 3:27pm UTC](https://discourse.julialang.org/t/imap-from-itertools-jl-doesnt-preserve-type/7683/2 "2017-12-11T15:27:12Z")

</div>

I think it is possible to define a type-stable iterator but it will need a special trick as `Base.Generator` does. `Core.Inference.return_type` can infer the return type as follows:

```julia
julia> Core.Inference.return_type(first, Tuple{typeof(2x for x in 1:10)})
Int64

```

I’m not a maintainer of IterTools.jl but it would be better to open an issue there.

---

<div class="post-metadata">

### Author: ![scelles](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scelles/32/220408_2.png) [@scelles](https://discourse.julialang.org/u/scelles)
#### Post date: [December 11, 2017, 3:46pm UTC](https://discourse.julialang.org/t/imap-from-itertools-jl-doesnt-preserve-type/7683/3 "2017-12-11T15:46:25Z")

</div>

Thanks @bicycle1885 issue opened [https://github.com/JuliaCollections/IterTools.jl/issues/15](https://github.com/JuliaCollections/IterTools.jl/issues/15)

---

<div class="post-metadata">

### Author: ![iamed2](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iamed2/32/215082_2.png) [@iamed2](https://discourse.julialang.org/u/iamed2)
#### Post date: [December 11, 2017, 7:12pm UTC](https://discourse.julialang.org/t/imap-from-itertools-jl-doesnt-preserve-type/7683/4 "2017-12-11T19:12:00Z")

</div>

All that’s needed is to define `iteratoreltype(::Type{<:IMap}) = EltypeUnknown()`! `collect` is pretty good at figuring out what the container type should be.

The real issue is I hadn’t tagged a release yet 🐑

---

<div class="post-metadata">

### Author: ![bicycle1885](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bicycle1885/32/107_2.png) [@bicycle1885](https://discourse.julialang.org/u/bicycle1885)
#### Post date: [December 12, 2017, 5:56am UTC](https://discourse.julialang.org/t/imap-from-itertools-jl-doesnt-preserve-type/7683/5 "2017-12-12T05:56:33Z")

</div>

Thank you. I didn’t know that!

---

<div class="post-metadata">

### Author: ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)
#### Post date: [December 12, 2017, 7:59am UTC](https://discourse.julialang.org/t/imap-from-itertools-jl-doesnt-preserve-type/7683/6 "2017-12-12T07:59:36Z")

</div>

`collect` also takes a type, so if you know the type `T` of the iterator (or if you want to `collect` to another type) you can do `collect(T, iter)`

```julia
julia> collect(Int, 1:2)
2-element Array{Int64,1}:
 1
 2

julia> collect(Complex{Float64}, 1:2)
2-element Array{Complex{Float64},1}:
 1.0 + 0.0im
 2.0 + 0.0im

```

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [December 12, 2017, 8:28am UTC](https://discourse.julialang.org/t/imap-from-itertools-jl-doesnt-preserve-type/7683/7 "2017-12-12T08:28:50Z")

</div>

What is it that you can do with an `imap` that you cannot achieve with a generator?

```julia
julia> g = (2x for x in 1:10)
Base.Generator{UnitRange{Int64},##21#22}(#21, 1:10)

julia> collect(g)
10-element Array{Int64,1}:
  2
  4
  6
  8
 10
 12
 14
 16
 18
 20

```

Neither one seems to work with broadcasting, and otherwise they seem similar.
