# Manipulating parametric types

**URL:** https://discourse.julialang.org/t/manipulating-parametric-types/6893
**Category:** General Usage
**Tags:** parametric-types
**Created:** [November 5, 2017, 8:34am UTC](https://discourse.julialang.org/t/manipulating-parametric-types/6893 "2017-11-05T08:34:33Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![robertfeldt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robertfeldt/32/239_2.png) [@robertfeldt](https://discourse.julialang.org/u/robertfeldt)
#### Post date: [November 5, 2017, 8:34am UTC](https://discourse.julialang.org/t/manipulating-parametric-types/6893/1 "2017-11-05T08:34:33Z")

</div>

I want to be able to manipulate parametric types for example to replace some type parameter with a different one. Since the name field of a DataType contains a TypeName and not the type itself and since it does not seem to be allowed to have variables in the place of a type when stating parametric type expressions I currently have a bit of an inflexible kludge of code for this. Is there some simpler, more natural, Julian way of achieving this:

```julia
function replaceparam(t, pi, st)
    newparams = collect(t.parameters)
    newparams[pi] = st
    newparams
end

# Not clear how we can get the parametric type from a composite one so we cheat
# by mapping to constructor functions from the type names.
TypeNameToReplaceFunction = Dict(
    Array.name => (t, i, st) -> Array{replaceparam(t, i, st)...},
    Dict.name => (t, i, st) -> Dict{replaceparam(t, i, st)...},
)

# Now we can create a new type from an existing one like for example:
t = Vector{String}
TypeNameToReplaceFunction[t.name](t, 1, AbstractString) # => Vector{AbstractString}
t2 = Dict{Int, Float64}
TypeNameToReplaceFunction[t2.name](t2, 2, String) # => Dict{Int64, String}

```

Any advice/hints on doing this in a more flexible, better way?

---

<div class="post-metadata">

### Author: ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)
#### Post date: [November 5, 2017, 4:49pm UTC](https://discourse.julialang.org/t/manipulating-parametric-types/6893/2 "2017-11-05T16:49:17Z")

</div>

There’s no official exported way to do these things, but I’ve got a [bunch of unexported but maintained functions in QuickTypes.jl](https://github.com/cstjean/QuickTypes.jl/blob/master/src/QuickTypes.jl#L26-L43) that may help. For instance

```julia
julia> using QuickTypes: roottype, type_parameters

julia> int2float_types(t) = roottype(t){(x===Int ? Float64 : x for x in type_parameters(t))...}
int2float_types (generic function with 1 method)

julia> int2float_types(Array{Int, 3})
Array{Float64,3}

julia> int2float_types(Tuple{String, Int})
Tuple{String,Float64}

```

Does that answer your question? I’m not 100% sure I understood what you’re trying to do.

---

<div class="post-metadata">

### Author: ![robertfeldt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robertfeldt/32/239_2.png) [@robertfeldt](https://discourse.julialang.org/u/robertfeldt)
#### Post date: [November 5, 2017, 6:31pm UTC](https://discourse.julialang.org/t/manipulating-parametric-types/6893/3 "2017-11-05T18:31:52Z")

</div>

Yes, thanks, indirectly it does. The `primary` field (on TypeName) is what I was missing. With that I can solve it. Big thanks!

---

<div class="post-metadata">

### Author: ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)
#### Post date: [November 5, 2017, 6:35pm UTC](https://discourse.julialang.org/t/manipulating-parametric-types/6893/4 "2017-11-05T18:35:53Z")

</div>

`primary` is gone in 0.6, so make a note to use the `Compat` version when you upgrade.

---

<div class="post-metadata">

### Author: ![jameson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jameson/32/23_2.png) [@jameson](https://discourse.julialang.org/u/jameson)
#### Post date: [November 7, 2017, 9:23pm UTC](https://discourse.julialang.org/t/manipulating-parametric-types/6893/5 "2017-11-07T21:23:57Z")

</div>

> [@cstjean](#):
>
> There’s no official exported way to do these things

The official, exported way to do this is to use `similar`.

While you can manipulate the type directly as done in QuickTypes, in general this is unsound (e.g. you must strongly avoid doing this in an `@generated` or `@pure` function). This will be mentioned in the manual in the next release [https://docs.julialang.org/en/latest/manual/methods/#Building-a-similar-type-with-a-different-type-parameter-1](https://docs.julialang.org/en/latest/manual/methods/#Building-a-similar-type-with-a-different-type-parameter-1), under the section “Design Patterns with Parametric Methods”.

---

<div class="post-metadata">

### Author: ![robertfeldt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robertfeldt/32/239_2.png) [@robertfeldt](https://discourse.julialang.org/u/robertfeldt)
#### Post date: [November 8, 2017, 8:52am UTC](https://discourse.julialang.org/t/manipulating-parametric-types/6893/6 "2017-11-08T08:52:06Z")

</div>

Thanks Jameson.

However, in my case I don’t want to convert any concrete data from one type to another, I need to actually find a way to dynamically apply one from a set of functions that has been defined for example for AbstractArray{Any,1} to an object of type Array{String,1}. By “going up” the normal type heirarchy with supertype I will traverse the “chain”: Array{String,1}, DenseArray{String,1}, AbstractArray{String,1}, Any. None of these will match the AbstractArray{Any,1} functions that could be applied in my case. Thus I want to manipulate the original Array{String,1} type and rather insert the types in String’s supertype “chain” (String, AbstractString, Any) into Array{X,1}. This will help me find the applicable AbstractArray{Any,1} functions in my case. The only way I have found so far is to manipulate the types in the style of QuickTypes.

Sorry if this is too terse to make any sense. If you have any ideas/inputs that is appreciated.

---

<div class="post-metadata">

### Author: ![jameson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jameson/32/23_2.png) [@jameson](https://discourse.julialang.org/u/jameson)
#### Post date: [November 8, 2017, 4:02pm UTC](https://discourse.julialang.org/t/manipulating-parametric-types/6893/7 "2017-11-08T16:02:23Z")

</div>

```julia
> typeintersect((Array{T, 1} where T >: String), AbstractArray{Any, 1})
Array{Any, 1}

```
