Search code examples
f#type-theory

Inferred curried function signatures in F#


In this article, this function

let adderGenerator numberToAdd = (+) numberToAdd

has this type signature

int -> (int -> int)

However, when I create this function, the inferred type signature is

int -> int -> int
  1. Are these type signatures different?
  2. If not, how can I annotate my adderGenerator so that it has the first type signature?

Edit 1
This is the best I could come up with so far:

type Generator = int -> (int -> int)
let adderGenerator: Generator = (+)

I don't like how it makes adderGenerator adopt a point-free style.

Edit 2
This seems to work:

let adderGenerator numberToAdd : (int -> int) = (+) numberToAdd

Solution

  • The type signatures are the same, the parentheses just help indicate that the body of the function results in a function being returned.

    These three forms with the full type annotated are equivalent:

    let adderGenerator : int -> int -> int =
        (+)
    
    let adderGenerator (numberToAdd : int) : int -> int =
        (+) numberToAdd
    
    let adderGenerator : int -> int -> int =
        fun numberToAdd -> (+) numberToAdd
    

    The first form is just an alias for + and simply reiterates its type.

    The second form is a function declaration that annotates the type of the argument and return type separately.

    The third form is a variable assigned an anonymous function.

    Only making one argument explicit seems a bit odd to me, however. You can avoid partial application entirely by making both arguments explicit:

    let adderGenerator (a : int) (b : int) : int =
        (+) a b
    
    let adderGenerator : int -> int -> int =
        fun a b -> (+) a b