# Reference: functions¶

This page gives reference information on functions in DAML:

DAML is a functional language. It lets you apply functions partially and also have functions that take other functions as arguments. This page discusses these *higher-order functions*.

## Defining functions¶

In Reference: expressions, the `tubeSurfaceArea`

function was defined as:

```
tubeSurfaceArea : Decimal -> Decimal -> Decimal
tubeSurfaceArea r h =
2.0 * pi * r * h
```

You can define this function equivalently using lambdas, involving `, a sequence of parameters, and an arrow `->`

as:

```
tubeSurfaceArea : BinaryDecimalFunction =
\ (r : Decimal) (h : Decimal) -> 2.0 * pi * r * h
```

## Partial application¶

The type of the `tubeSurfaceArea`

function described previously, is `Decimal -> Decimal -> Decimal`

. An equivalent, but more instructive, way to read its type is: `Decmial -> (Decimal -> Decimal)`

: saying that `tubeSurfaceArea`

is a function that takes *one* argument and returns another function.

So `tubeSurfaceArea`

expects one argument of type `Decimal`

and returns a function of type `Decimal -> Decimal`

. In other words, this function returns another function. *Only the last application of an argument yields a non-function.*

This is called *currying*: currying is the process of converting a function of multiple arguments to a function that takes just a single argument and returns another function. In DAML, all functions are curried.

This doesn’t affect things that much. If you use functions in the classical way (by applying them to all parameters) then there is no difference.

If you only apply a few arguments to the function, this is called *partial application*. The result is a function with partially defined arguments. For example:

```
multiplyThreeNumbers : Int -> Int -> Int -> Int
multiplyThreeNumbers xx yy zz =
xx * yy * zz
multiplyTwoNumbersWith7 = multiplyThreeNumbers 7
multiplyWith21 = multiplyTwoNumbersWith7 3
multiplyWith18 = multiplyThreeNumbers 3 6
```

You could also define equivalent lambda functions:

```
multiplyWith18_v2 : Int -> Int
multiplyWith18_v2 xx =
multiplyThreeNumbers 3 6 xx
```

## Functions are values¶

The function type can be explicitly added to the `tubeSurfaceArea`

function (when it is written with the lambda notation):

```
-- Type synonym for Decimal -> Decimal -> Decimal
type BinaryDecimalFunction = Decimal -> Decimal -> Decimal
pi : Decimal = 3.1415926535
tubeSurfaceArea : BinaryDecimalFunction =
\ (r : Decimal) (h : Decimal) -> 2.0 * pi * r * h
```

Note that `tubeSurfaceArea : BinaryDecimalFunction = ...`

follows the same pattern as when binding values, e.g., `pi : Decimal = 3.14159265359`

.

Functions have types, just like values. Which means they can be used just like normal variables. In fact, in DAML, functions are values.

This means a function can take another function as an argument. For example, define a function `applyFilter: (Int -> Int -> Bool) -> Int -> Int -> Bool`

which applies the first argument, a higher-order function, to the second and the third arguments to yield the result.

```
applyFilter (filter : Int -> Int -> Bool)
(x : Int)
(y : Int) = filter x y
compute = scenario do
assert (applyFilter (<) 3 2 == False)
assert (applyFilter (/=) 3 2 == True)
assert (round (2.5 : Decimal) == 3)
assert (round (3.5 : Decimal) == 4)
assert (explode "me" == ["m", "e"])
assert (applyFilter (\a b -> a /= b) 3 2 == True)
```

The Folding section looks into two useful built-in functions, `foldl`

and `foldr`

, that also take a function as an argument.

Note

DAML does not allow functions as parameters of contract templates and contract choices. However, a follow up of a choice can use built-in functions, defined at the top level or in the contract template body.

## Generic functions¶

A function is *parametrically polymorphic* if it behaves uniformly for all types, in at least one of its type parameters. For example, you can define function composition as follows:

```
compose (f : b -> c) (g : a -> b) (x : a) : c = f (g x)
```

where `a`

, `b`

, and `c`

are any data types. Both `compose ((+) 4) ((*) 2) 3 == 10`

and `compose not ((&&) True) False`

evaluate to `True`

. Note that `((+) 4)`

has type `Int -> Int`

, whereas `not`

has type `Bool -> Bool`

.

You can find many other generic functions including this one in the DAML standard library.

Note

DAML currently does not support generic functions for a specific set of types, such as `Int`

and `Decimal`

numbers. For example, `sum (x: a) (y: a) = x + y`

is undefined when `a`

equals the type `Party`

. *Bounded polymorphism* might be added to DAML in a later version.