Function Type

In Cangjie, a function is a first-class citizen. It can be used as a parameter or return value of a function and assigned to a variable. Therefore, the function type can be defined.

The function type consists of the parameter type and return type, which are connected using ->. The parameter type is enclosed in parentheses (()). There can be no or multiple parameters. If there are more than one parameter, parameter types are separated by commas (,).

The following is an example:

func hello(): Unit {
    println("Hello!")
}

The preceding example defines a function named hello whose function type is () -> Unit, indicating that the function has no parameter and its return type is Unit.

The following are some other examples:

  • This example defines a function named display whose function type is (Int64) -> Unit, indicating that the function has a parameter of the Int64 type and its return type is Unit.

    func display(a: Int64): Unit {
        println(a)
    }
    
  • This example defines a function named add whose function type is (Int64, Int64) -> Int64, indicating that the function has two parameters of the Int64 type and its return type is Int64.

    func add(a: Int64, b: Int64): Int64 {
        a + b
    }
    
  • This example defines a function named returnTuple whose function type is (Int64, Int64) -> (Int64, Int64), indicating that the function has two parameters of the Int64 type, and its return type is the tuple (Int64, Int64).

    func returnTuple(a: Int64, b: Int64): (Int64, Int64) {
        (a, b)
    }
    

Type Parameter

You can use explicit type parameter names in the function type, such as the name and price in the following example:

func showFruitPrice(name: String, price: Int64) {
    println("fruit: ${name} price: ${price} yuan")
}

main() {
    let fruitPriceHandler: (name: String, price: Int64) -> Unit
    fruitPriceHandler = showFruitPrice
    fruitPriceHandler("banana", 10)
}

In addition, you need to specify either all type parameter names or no type parameter names in the function type.

let handler: (name: String, Int64) -> Int64   // Error

Function Type as a Parameter Type

For example, if the type of the printAdd function is ((Int64, Int64) -> Int64, Int64, Int64) -> Unit, the function has three parameters, among which one is of the (Int64, Int64) -> Int64 type and two are of the Int64 type, and its return type is Unit.

func printAdd(add: (Int64, Int64) -> Int64, a: Int64, b: Int64): Unit {
    println(add(a, b))
}

Function Type as a Return Type

A function type can be used as the return type of another function.

In the following example, the type of the returnAdd function is () -> (Int64, Int64) -> Int64, indicating that the function has no parameter, and its return type is (Int64, Int64) -> Int64: Note that -> is right associative.

func add(a: Int64, b: Int64): Int64 {
    a + b
}

func returnAdd(): (Int64, Int64) -> Int64 {
    add
}

main() {
    var a = returnAdd()
    println(a(1,2))
}

Function Type as a Variable Type

If the name of a function is an expression, its type is the function type of the expression.

func add(p1: Int64, p2: Int64): Int64 {
    p1 + p2
}

let f: (Int64, Int64) -> Int64 = add

In the preceding example, the type of the add function is (Int64, Int64) -> Int64, the type of the f variable is the same as that of add, and add is used to initialize f.

If a function is overloaded in the current scope (for details, see Function Overloading), using its function name as an expression may cause ambiguity, which may result in an error reported by the compiler. The following is an example:

func add(i: Int64, j: Int64) {
    i + j
}

func add(i: Float64, j: Float64) {
    i + j
}

main() {
    var f = add   // Error, ambiguous function 'add'
    var plus: (Int64, Int64) -> Int64 = add  // OK
}