# How to type annotate functions which take functions as args

**URL:** <https://discourse.julialang.org/t/how-to-type-annotate-functions-which-take-functions-as-args/14158>\
**Category:** New to Julia\
**Created:** [August 27, 2018, 10:25pm UTC](https://discourse.julialang.org/t/how-to-type-annotate-functions-which-take-functions-as-args/14158 "2018-08-27T22:25:14Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Alex\_Ellison](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alex_ellison/32/5749_2.png) [@Alex\_Ellison](https://discourse.julialang.org/u/Alex_Ellison)\
**Post date:** [August 27, 2018, 10:25pm UTC](https://discourse.julialang.org/t/how-to-type-annotate-functions-which-take-functions-as-args/14158/1 "2018-08-27T22:25:14Z")

</div>

Hi there,  
Julia’s dispatch is something we all love, but I can’t figure out the syntax for the case of creating the signature of a function which takes another function as an arg.

```julia
               _
   _ _ _(_)_ | Documentation: https://docs.julialang.org
  (_) | (_) (_) |
   _ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` | |
  | | |_| | | | (_| | | Version 1.0.0 (2018-08-08)
 _/ |\ __'_|_|_|\__'_| | Official https://julialang.org/ release
|__/ |

julia> function f(x::Number)
              return x^2+1
              end
f (generic function with 1 method)

julia> function g(x::Number)
              return sqrt(x-1)
              end
g (generic function with 1 method)

julia> f(2)
5

julia> g(5)
2.0

julia> function h(_f, x :: Number)
              return g(_f(x))
              end
h (generic function with 1 method)

julia> h(f, 1)
1.0

```

If I wanted to annotate the function h’s arg \_f, how would I do so? I was hoping for something like Haskell where you could say a-\>a (NB, I’m not a haskell programmer but I’m acquainted with the concepts). I suspect I don’t fully understand Julia’s type system when it comes to functions because if I try…

```julia
julia> typeof(h)
typeof(h)

```

… I get output which to me seems unhelpful. While my code works without such an annotation, I hope making that explicit is supported syntax.

If you think you see the gap in my understanding and/or have resources explaining this part of the language I’d be very grateful!  
Cheers

---

<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:** [August 27, 2018, 10:28pm UTC](https://discourse.julialang.org/t/how-to-type-annotate-functions-which-take-functions-as-args/14158/2 "2018-08-27T22:28:50Z")

</div>

> [@Alex\_Ellison](#):
>
> if I try…
> 
> ```julia
> julia> typeof(h)
> typeof(h)
> 
> ```
> 
> … I get output which to me seems unhelpful.

Did you try to annotate `_f` with this? It actually works!

```julia
julia> function h(_f::typeof(f), x::Number)
           return g(_f(x))
       end
h (generic function with 1 method)

julia> h(f, 1)
1.0

julia> h(g, 1)
ERROR: MethodError: no method matching h(::typeof(g), ::Int64)
Closest candidates are:
  h(::typeof(f), ::Number) at REPL[26]:2
Stacktrace:
 [1] top-level scope at none:0

```

---

<div class="post-metadata">

**Author:** ![dawbarton](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dawbarton/32/215461_2.png) [@dawbarton](https://discourse.julialang.org/u/dawbarton)\
**Post date:** [August 27, 2018, 11:04pm UTC](https://discourse.julialang.org/t/how-to-type-annotate-functions-which-take-functions-as-args/14158/3 "2018-08-27T23:04:41Z")

</div>

Alternatively if you just want your function `h` to call any function passed, not just `f` (which is presumably the case since otherwise you wouldn’t have it as an argument and just fixed in the code) you can use the `::Function` annotation. (I don’t know Haskell so I can’t tell if that’s what you are trying to do.) For example,

```julia
julia> function h(_f::Function, x::Number)
           return g(_f(x))
       end
h (generic function with 1 method)

julia> supertype(typeof(f))
Function

julia> f isa Function
true

julia> g isa Function
true

```

That said, it’s often useful not to restrict functions to subtypes of `Function` since there are other ways of creating objects that you can call. For example, you can have a callable struct.

```julia
struct MyStruct
    a::Float64
end

function (mystruct::MyStruct)(b::Number)
    mystruct.a + b
end

julia> astruct = MyStruct(1.2)
MyStruct(1.2)

julia> astruct(3)
4.2

julia> astruct isa Function
false

```

As such, I tend to leave off function annotations and just try calling whatever is passed. (Cf. [duck typing](https://en.wikipedia.org/wiki/Duck_typing).)

---

<div class="post-metadata">

**Author:** ![ggggggggg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ggggggggg/32/265_2.png) [@ggggggggg](https://discourse.julialang.org/u/ggggggggg)\
**Post date:** [August 28, 2018, 3:53am UTC](https://discourse.julialang.org/t/how-to-type-annotate-functions-which-take-functions-as-args/14158/4 "2018-08-28T03:53:42Z")

</div>

> [@Alex\_Ellison](#):
>
> a-\>a

I’m pretty sure in Haskell this means something like “a function with one argument, and one return value, which both have the same type”. Is that right? I don’t think you can do that in Julia, at least partially because functions can’t be described in that way. Consider

```julia
f(x)=1
f(x,y)=2

```

The function `f` cannot be described with a single number of arguments, because it has methods with many numbers of arguments.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [August 28, 2018, 4:15am UTC](https://discourse.julialang.org/t/how-to-type-annotate-functions-which-take-functions-as-args/14158/5 "2018-08-28T04:15:11Z")

</div>

A couple of relevant prior discussions, in case you’re interested:

- [Ability to define function templates - #7 by jeff.bezanson](https://discourse.julialang.org/t/ability-to-define-function-templates/4867/7)
- [Function Parameter Speculation #17168 - #7 by jameson](https://discourse.julialang.org/t/function-parameter-speculation-17168/1677/7)
- [Proposal for a first-class dispatch wrapper](https://discourse.julialang.org/t/proposal-for-a-first-class-dispatch-wrapper/1127)
