66 lines
1.4 KiB
Markdown
66 lines
1.4 KiB
Markdown
## Introducing Definitions
|
||
|
||
The ``def`` command provides one important way of defining new objects.
|
||
|
||
```lean
|
||
|
||
def foo : (Nat → Nat) → Nat :=
|
||
fun f => f 0
|
||
|
||
#check foo -- (Nat → Nat) → Nat
|
||
#print foo
|
||
```
|
||
|
||
We can omit the type when Lean has enough information to infer it:
|
||
|
||
```lean
|
||
def foo :=
|
||
fun (f : Nat → Nat) => f 0
|
||
```
|
||
|
||
The general form of a definition is ``def foo : α := bar``. Lean can usually infer the type ``α``, but it is often a good idea to write it explicitly.
|
||
This clarifies your intention, and Lean will flag an error if the right-hand side of the definition does not have the right type.
|
||
|
||
Lean also allows us to use an alternative format that puts the abstracted variables before the colon and omits the lambda:
|
||
```lean
|
||
def double (x : Nat) : Nat :=
|
||
x + x
|
||
|
||
#print double
|
||
#check double 3
|
||
#reduce double 3 -- 6
|
||
#eval double 3 -- 6
|
||
|
||
def square (x : Nat) :=
|
||
x * x
|
||
|
||
#print square
|
||
#check square 3
|
||
#reduce square 3 -- 9
|
||
#eval square 3 -- 9
|
||
|
||
def doTwice (f : Nat → Nat) (x : Nat) : Nat :=
|
||
f (f x)
|
||
|
||
#eval doTwice double 2 -- 8
|
||
```
|
||
|
||
These definitions are equivalent to the following:
|
||
|
||
```lean
|
||
def double : Nat → Nat :=
|
||
fun x => x + x
|
||
|
||
def square : Nat → Nat :=
|
||
fun x => x * x
|
||
|
||
def doTwice : (Nat → Nat) → Nat → Nat :=
|
||
fun f x => f (f x)
|
||
```
|
||
|
||
We can even use this approach to specify arguments that are types:
|
||
|
||
```lean
|
||
def compose (α β γ : Type) (g : β → γ) (f : α → β) (x : α) : γ :=
|
||
g (f x)
|
||
```
|