# Creating an abstract type as a wrapper for types different functions that serve the same purpose

**URL:** <https://discourse.julialang.org/t/creating-an-abstract-type-as-a-wrapper-for-types-different-functions-that-serve-the-same-purpose/44758>\
**Category:** General Usage\
**Tags:** question, parametric-types\
**Created:** [August 11, 2020, 8:23pm UTC](https://discourse.julialang.org/t/creating-an-abstract-type-as-a-wrapper-for-types-different-functions-that-serve-the-same-purpose/44758 "2020-08-11T20:23:56Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![gottacatchenall](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gottacatchenall/32/18265_2.png) [@gottacatchenall](https://discourse.julialang.org/u/gottacatchenall)\
**Post date:** [August 11, 2020, 8:23pm UTC](https://discourse.julialang.org/t/creating-an-abstract-type-as-a-wrapper-for-types-different-functions-that-serve-the-same-purpose/44758/1 "2020-08-11T20:23:56Z")

</div>

I’m trying to create an `abstract type` that is a superclass (called `Kernel`) several different of functions, each a subclass of `Kernel` --i.e.

```julia
abstract type Kernel end

struct ExponentialKernel <: Kernel
    ExponentialKernel(rate::Number, x::Number) = exp(-1*rate*x)
end

struct GaussianKernel <: Kernel
    GaussianKernel(sigma::Number, x::Number) = (1.0/(sigma*sqrt(2*pi))) * exp((-1*x^2)/(2*sigma^2)
end

...

```

and so on.

When I use what I have above, it works in the sense that when I call `ExpKernel(a,b)` I get the right value, but when I try to pass these kernel objects to a different constructor, like

```julia
mutable struct Model
    kernel::T where {T <: Kernel}    

    Model(kernel) = new(kernel) 
end

```

When I call `Model(ExpKernel)` I get the error

```julia
ERROR: MethodError: Cannot `convert` an object of type Type{ExpKernel} to an object of type Kernel

```

Is there something I’m missing about types here?

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [August 11, 2020, 8:36pm UTC](https://discourse.julialang.org/t/creating-an-abstract-type-as-a-wrapper-for-types-different-functions-that-serve-the-same-purpose/44758/2 "2020-08-11T20:36:59Z")

</div>

You can either do

```julia
struct Model
    kernel::Kernel
end

```

or

```julia
struct Model{T <: Kernel}
    kernel::T
end

```

In the first one, `Model` does not have information in its type about which kernel it stores. This will probably lead to a performance penalty for you, but that can’t be said for sure without knowing the context.  
The second one is a parametric type, parameterized by which kernel type it stores. Note that I made the type immutable. I expect that’s probably what you want also, as I don’t expect there is value in a mutable kernel (I could be wrong), and mutability also often comes with a performance penalty.

* * *

Although it was not part of the question:

```julia
struct ExponentialKernel <: Kernel
    ExponentialKernel(rate::Number, x::Number) = exp(-1*rate*x)
end

```

I don’t think what you wrote does what you want:

```julia
julia> ExponentialKernel(5, 5)
1.3887943864964021e-11

```
