155 lines
2.9 KiB
Markdown
155 lines
2.9 KiB
Markdown
# Functions
|
|
|
|
- Functions accept a single input and produce an output.
|
|
- All functions are inherently curried.
|
|
|
|
## Private Functions
|
|
|
|
- Any function may be marked `private`.
|
|
- `private` functions are only available in the current scope.
|
|
- Scope is file, class, instance, etc. (any function holder)
|
|
- `private` functions are NOT exported.
|
|
|
|
```
|
|
given F *
|
|
class Functor
|
|
given A, B
|
|
fn map: (A -> B) -> F A -> F B
|
|
end class
|
|
|
|
instance Functor List
|
|
given A, B
|
|
fn map: (A -> B) -> [A] -> [B]
|
|
case _ [] => []
|
|
case f [h : t] => f h : map f t
|
|
end fn
|
|
end instance
|
|
```
|
|
|
|
```
|
|
map (+ 1) [1, 2, 3]
|
|
-- produces [2, 3, 4]
|
|
|
|
-- Assuming F is given, F A -> F B
|
|
let plus_one := map (+ 1)
|
|
```
|
|
|
|
note define infix in parens as prefix!!!
|
|
|
|
```
|
|
given F * *
|
|
Map String Int32
|
|
|
|
-- F[*[*]]
|
|
given F (* *)
|
|
List (List String)
|
|
```
|
|
|
|
## Syntax
|
|
|
|
```
|
|
[given T1, T2, ... TN]
|
|
fn <name>: <input> => <output>
|
|
<body>
|
|
end fn
|
|
```
|
|
|
|
- `TN`: Type declaration (e.g. A :: Show)
|
|
- `name`: Follows the rules for [names](names.md)
|
|
- `input`: One or more named tuples ([records](records.md)).
|
|
- `output`: Some type.
|
|
- `body`: Function definition.
|
|
|
|
Note that `<input> => <output>` is the type of a function.
|
|
|
|
## Function Definitions
|
|
|
|
Function definitions are a series of expressions, where the value of the last
|
|
expression is returned.
|
|
|
|
```
|
|
fn example: (x: Int32, y: Int32) => Int32
|
|
let xx := x + 1
|
|
let yy := y + 1
|
|
xx * yy
|
|
end fn
|
|
```
|
|
|
|
## Calling Functions
|
|
|
|
Calling a function involves passing that function the tuples it needs.
|
|
|
|
```
|
|
given A :: Show
|
|
fn example: (a: A) => String
|
|
show(a)
|
|
end fn
|
|
|
|
fn calling_a_function: () => Task[()]
|
|
let x := 1
|
|
let y := true
|
|
let z := "foo"
|
|
println(show(x) + show(y) + show(z))
|
|
end fn
|
|
```
|
|
|
|
### Calling with Tuples
|
|
|
|
```
|
|
fn example: (x: Int32, y: Int32: z: Int32) => Int32
|
|
x + y + z
|
|
end fn
|
|
|
|
let inputs := (10, 20, 30)
|
|
example inputs
|
|
```
|
|
|
|
```
|
|
fn example: (x: Int32, y: Int32)(z: Int32, w: Int32) => Int32
|
|
x + y + z + w
|
|
end fn
|
|
|
|
let in1 := (1, 2)
|
|
let in2 := (3, 4)
|
|
example in1 in2
|
|
example (1, 2) in2
|
|
example in1 (3, 4)
|
|
```
|
|
|
|
## Generic Functions
|
|
|
|
## Referencing Arguments
|
|
|
|
`@args` refers to function arguments.
|
|
|
|
- For a single parameter list, it refers to the record.
|
|
- For multiple parameter lists, it refers to a tuple containing the lists in
|
|
order.
|
|
|
|
## Lazy Arguments
|
|
|
|
The `lazy` keyword allows the expression providing the value to have evaluation
|
|
deferred until the value is _used_ in the function. If the value is not used,
|
|
the expression is never evaluated.
|
|
|
|
```
|
|
fn foo: (lazy x: Int32) => Int32
|
|
x * 2
|
|
end fn
|
|
```
|
|
|
|
Note that this is equivalent to encoding a parameter as a synchronous effect and
|
|
evaluating it to value when needed.
|
|
|
|
## Function Composition
|
|
|
|
```
|
|
given A, B, C
|
|
fn compose: (f: (B) => C, g: (A) => B) => (A) => C
|
|
x => f(g(x))
|
|
end fn
|
|
```
|
|
|
|
## Variable Length Argument Lists
|
|
|
|
This feature is explicitly not supported by Ava. Lists should be used instead.
|