Using types as parameters of a function

We have the following code:

abstract type  MyType end 
struct  MyType1 <: MyType  end 
myfun(::MyType1,  x,  args...) = x 

How can I call the function ‘myfun’?

julia> myfun(::MyType1, 2)
ERROR: syntax: invalid "::" syntax around REPL[10]:1
Stacktrace:
 [1] top-level scope
   @ REPL[10]:1

julia> myfun(:MyType1, 2)
ERROR: MethodError: no method matching myfun(::Symbol, ::Int64)

Closest candidates are:
  myfun(::MyType1, ::Any, ::Any...)
   @ Main REPL[5]:1

Stacktrace:
 [1] top-level scope
   @ REPL[11]:1

julia> myfun(MyType1, 2)
ERROR: MethodError: no method matching myfun(::Type{MyType1}, ::Int64)

Closest candidates are:
  myfun(::MyType1, ::Any, ::Any...)
   @ Main REPL[5]:1

Stacktrace:
 [1] top-level scope
   @ REPL[12]:1

I am really confused with the ::

The double-colon is used to declare the argument type. I am sure you have seen

f(x::Int) = # some definition

which means that f accepts an argument of type Int.

When a function does not manipulate with an argument and only cares about the argument’s type, you can omit the argument’s name:

f(::Int) = # something

You can still call it as, e.g., f(3).

In your case, you have

myfun(::MyType1, x, args...)

so you need to pass an instance of MyType1. For example:

myfun(MyType1(), 2)
3 Likes

There’s another way to define the function signature that lets you call it with a type instead of an instance. While

myfun(::MyType1, x, args...) 

takes an instance as the first argument,

myfun(::Type{MyType1}, x, args...) 

takes the type itself, and can be called as

myfun(MyType1, 2)

It’s not always you can trivially instantiate a type, for example Float64() does not work, you need to create a specific value. For some types this could be difficult or expensive.

3 Likes

See also Type{T} in the manual.

2 Likes