Improvements from Sander and JDP.
This commit is contained in:
parent
61ec0f41c3
commit
3583f72cb4
@ -386,13 +386,14 @@ type return = (list (operation), storage);
|
|||||||
|
|
||||||
let dest : address = ("KT19wgxcuXG9VH4Af5Tpm1vqEKdaMFpznXT3" : address);
|
let dest : address = ("KT19wgxcuXG9VH4Af5Tpm1vqEKdaMFpznXT3" : address);
|
||||||
|
|
||||||
let proxy = ((param, store): (parameter, storage)) : return =>
|
let proxy = ((param, store): (parameter, storage)) : return => {
|
||||||
let counter : contract (parameter) = Operation.get_contract (dest);
|
let counter : contract (parameter) = Operation.get_contract (dest);
|
||||||
(* Reuse the parameter in the subsequent
|
(* Reuse the parameter in the subsequent
|
||||||
transaction or use another one, `mock_param`. *)
|
transaction or use another one, `mock_param`. *)
|
||||||
let mock_param : parameter = Increment (5n);
|
let mock_param : parameter = Increment (5n);
|
||||||
let op : operation = Operation.transaction (param, 0mutez, counter);
|
let op : operation = Operation.transaction (param, 0mutez, counter);
|
||||||
([op], store);
|
([op], store)
|
||||||
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
@ -101,8 +101,8 @@ let in_24_hrs : timestamp = today - one_day;
|
|||||||
|
|
||||||
### Comparing Timestamps
|
### Comparing Timestamps
|
||||||
|
|
||||||
You can also compare timestamps using the same comparison operators as
|
You can compare timestamps using the same comparison operators
|
||||||
for numbers.
|
applying to numbers.
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
<!--Pascaligo-->
|
<!--Pascaligo-->
|
||||||
@ -124,10 +124,10 @@ let not_tomorrow : bool = (Current.time == in_24_hrs);
|
|||||||
|
|
||||||
## Addresses
|
## Addresses
|
||||||
|
|
||||||
The type `address` in LIGO is used to denote Tezos addresses (tz1,
|
The type `address` in LIGO denotes Tezos addresses (tz1, tz2, tz3,
|
||||||
tz2, tz3, KT1, ...). Currently, addresses are created by casting a
|
KT1, ...). Currently, addresses are created by casting a string to the
|
||||||
string to the type `address`. Beware of failures if the address is
|
type `address`. Beware of failures if the address is invalid. Consider
|
||||||
invalid. Consider the following examples.
|
the following examples.
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
<!--Pascaligo-->
|
<!--Pascaligo-->
|
||||||
@ -152,7 +152,7 @@ let my_account : address =
|
|||||||
|
|
||||||
## Signatures
|
## Signatures
|
||||||
|
|
||||||
The type `signature` in LIGO datatype is used for Tezos signature
|
The `signature` type in LIGO datatype is used for Tezos signatures
|
||||||
(edsig, spsig). Signatures are created by casting a string. Beware of
|
(edsig, spsig). Signatures are created by casting a string. Beware of
|
||||||
failure if the signature is invalid.
|
failure if the signature is invalid.
|
||||||
|
|
||||||
@ -181,7 +181,7 @@ signature);
|
|||||||
|
|
||||||
## Keys
|
## Keys
|
||||||
|
|
||||||
The type `key` in LIGO is used for Tezos public keys. Do not confuse
|
The `key` type in LIGO is used for Tezos public keys. Do not confuse
|
||||||
them with map keys. Keys are made by casting strings. Beware of
|
them with map keys. Keys are made by casting strings. Beware of
|
||||||
failure if the key is invalid.
|
failure if the key is invalid.
|
||||||
|
|
||||||
|
@ -34,7 +34,10 @@ In LIGO, only values of the same type can be compared. Moreover, not
|
|||||||
all values of the same type can be compared, only those with
|
all values of the same type can be compared, only those with
|
||||||
*comparable types*, which is a concept lifted from
|
*comparable types*, which is a concept lifted from
|
||||||
Michelson. Comparable types include, for instance, `int`, `nat`,
|
Michelson. Comparable types include, for instance, `int`, `nat`,
|
||||||
`string`, `tez`, `timestamp`, `address`, etc.
|
`string`, `tez`, `timestamp`, `address`, etc. As an example of
|
||||||
|
non-comparable types: maps, sets or lists are not comparable: if you
|
||||||
|
wish to compare them, you will have to write your own comparison
|
||||||
|
function.
|
||||||
|
|
||||||
### Comparing Strings
|
### Comparing Strings
|
||||||
|
|
||||||
@ -110,7 +113,7 @@ let h : bool = (a != b);
|
|||||||
```pascaligo group=d
|
```pascaligo group=d
|
||||||
const a : tez = 5mutez
|
const a : tez = 5mutez
|
||||||
const b : tez = 10mutez
|
const b : tez = 10mutez
|
||||||
const c : bool = (a = b) // false
|
const c : bool = (a = b) // False
|
||||||
```
|
```
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
```cameligo group=d
|
```cameligo group=d
|
||||||
@ -129,7 +132,7 @@ let c : bool = (a == b); // false
|
|||||||
|
|
||||||
## Conditionals
|
## Conditionals
|
||||||
|
|
||||||
Conditional logic enables to fork the control flow depending on the
|
Conditional logic enables forking the control flow depending on the
|
||||||
state.
|
state.
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
@ -10,11 +10,11 @@ logic into functions.
|
|||||||
## Blocks
|
## Blocks
|
||||||
|
|
||||||
In PascaLIGO, *blocks* enable the sequential composition of
|
In PascaLIGO, *blocks* enable the sequential composition of
|
||||||
*instructions* into an isolated scope. Each `block` needs to include
|
instructions into an isolated scope. Each block needs to include at
|
||||||
at least one instruction. If we need a placeholder *placeholder*, we
|
least one instruction. If we need a placeholder, we use the
|
||||||
use the instruction called `skip`, that leaves the state
|
instruction `skip` which leaves the state unchanged. The rationale
|
||||||
invariant. The rationale for `skip` instead of a truly empty block is
|
for `skip` instead of a truly empty block is that it prevents you from
|
||||||
that it prevents you from writing an empty block by mistake.
|
writing an empty block by mistake.
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
<!--Pascaligo-->
|
<!--Pascaligo-->
|
||||||
@ -31,10 +31,10 @@ Blocks are more versatile than simply containing instructions:
|
|||||||
they can also include *declarations* of values, like so:
|
they can also include *declarations* of values, like so:
|
||||||
```pascaligo skip
|
```pascaligo skip
|
||||||
// terse style
|
// terse style
|
||||||
block { const a : int = 1; }
|
block { const a : int = 1 }
|
||||||
// verbose style
|
// verbose style
|
||||||
begin
|
begin
|
||||||
const a : int = 1;
|
const a : int = 1
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ to have a special type: if the type of the accumulator is `t`, then it
|
|||||||
must have the type `bool * t` (not simply `t`). It is the boolean
|
must have the type `bool * t` (not simply `t`). It is the boolean
|
||||||
value that denotes whether the stopping condition has been reached.
|
value that denotes whether the stopping condition has been reached.
|
||||||
|
|
||||||
```cameligo group=b
|
```cameligo group=a
|
||||||
let iter (x,y : nat * nat) : bool * (nat * nat) =
|
let iter (x,y : nat * nat) : bool * (nat * nat) =
|
||||||
if y = 0n then false, (x,y) else true, (y, x mod y)
|
if y = 0n then false, (x,y) else true, (y, x mod y)
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ let gcd (x,y : nat * nat) : nat =
|
|||||||
To ease the writing and reading of the iterated functions (here,
|
To ease the writing and reading of the iterated functions (here,
|
||||||
`iter`), two predefined functions are provided: `continue` and `stop`:
|
`iter`), two predefined functions are provided: `continue` and `stop`:
|
||||||
|
|
||||||
```cameligo group=c
|
```cameligo group=a
|
||||||
let iter (x,y : nat * nat) : bool * (nat * nat) =
|
let iter (x,y : nat * nat) : bool * (nat * nat) =
|
||||||
if y = 0n then stop (x,y) else continue (y, x mod y)
|
if y = 0n then stop (x,y) else continue (y, x mod y)
|
||||||
|
|
||||||
@ -113,27 +113,29 @@ accumulator is `t`, then it must have the type `bool * t` (not simply
|
|||||||
`t`). It is the boolean value that denotes whether the stopping
|
`t`). It is the boolean value that denotes whether the stopping
|
||||||
condition has been reached.
|
condition has been reached.
|
||||||
|
|
||||||
```reasonligo group=d
|
```reasonligo group=a
|
||||||
let iter = ((x,y) : (nat, nat)) : (bool, (nat, nat)) =>
|
let iter = ((x,y) : (nat, nat)) : (bool, (nat, nat)) =>
|
||||||
if (y == 0n) { (false, (x,y)); } else { (true, (y, x mod y)); };
|
if (y == 0n) { (false, (x,y)); } else { (true, (y, x mod y)); };
|
||||||
|
|
||||||
let gcd = ((x,y) : (nat, nat)) : nat =>
|
let gcd = ((x,y) : (nat, nat)) : nat => {
|
||||||
let (x,y) = if (x < y) { (y,x); } else { (x,y); };
|
let (x,y) = if (x < y) { (y,x); } else { (x,y); };
|
||||||
let (x,y) = Loop.fold_while (iter, (x,y));
|
let (x,y) = Loop.fold_while (iter, (x,y));
|
||||||
x;
|
x
|
||||||
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
To ease the writing and reading of the iterated functions (here,
|
To ease the writing and reading of the iterated functions (here,
|
||||||
`iter`), two predefined functions are provided: `continue` and `stop`:
|
`iter`), two predefined functions are provided: `continue` and `stop`:
|
||||||
|
|
||||||
```reasonligo group=e
|
```reasonligo group=b
|
||||||
let iter = ((x,y) : (nat, nat)) : (bool, (nat, nat)) =>
|
let iter = ((x,y) : (nat, nat)) : (bool, (nat, nat)) =>
|
||||||
if (y == 0n) { stop ((x,y)); } else { continue ((y, x mod y)); };
|
if (y == 0n) { stop ((x,y)); } else { continue ((y, x mod y)); };
|
||||||
|
|
||||||
let gcd = ((x,y) : (nat, nat)) : nat =>
|
let gcd = ((x,y) : (nat, nat)) : nat => {
|
||||||
let (x,y) = if (x < y) { (y,x); } else { (x,y); };
|
let (x,y) = if (x < y) { (y,x); } else { (x,y); };
|
||||||
let (x,y) = Loop.fold_while (iter, (x,y));
|
let (x,y) = Loop.fold_while (iter, (x,y));
|
||||||
x;
|
x
|
||||||
|
};
|
||||||
```
|
```
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
@ -147,7 +149,7 @@ To iterate over a range of integers you use a loop of the form `for
|
|||||||
familiar for programmers of imperative languages. Note that, for the
|
familiar for programmers of imperative languages. Note that, for the
|
||||||
sake of generality, the bounds are of type `int`, not `nat`.
|
sake of generality, the bounds are of type `int`, not `nat`.
|
||||||
|
|
||||||
```pascaligo group=f
|
```pascaligo group=c
|
||||||
function sum (var n : nat) : int is block {
|
function sum (var n : nat) : int is block {
|
||||||
var acc : int := 0;
|
var acc : int := 0;
|
||||||
for i := 1 to int (n) block {
|
for i := 1 to int (n) block {
|
||||||
@ -177,7 +179,7 @@ of the form `for <element var> in <collection type> <collection var>
|
|||||||
|
|
||||||
Here is an example where the integers in a list are summed up.
|
Here is an example where the integers in a list are summed up.
|
||||||
|
|
||||||
```pascaligo group=g
|
```pascaligo group=d
|
||||||
function sum_list (var l : list (int)) : int is block {
|
function sum_list (var l : list (int)) : int is block {
|
||||||
var total : int := 0;
|
var total : int := 0;
|
||||||
for i in list l block {
|
for i in list l block {
|
||||||
@ -197,7 +199,7 @@ gitlab-pages/docs/language-basics/src/loops/collection.ligo sum_list
|
|||||||
|
|
||||||
Here is an example where the integers in a set are summed up.
|
Here is an example where the integers in a set are summed up.
|
||||||
|
|
||||||
```pascaligo=g
|
```pascaligo=e
|
||||||
function sum_set (var s : set (int)) : int is block {
|
function sum_set (var s : set (int)) : int is block {
|
||||||
var total : int := 0;
|
var total : int := 0;
|
||||||
for i in set s block {
|
for i in set s block {
|
||||||
|
@ -358,7 +358,7 @@ let moves : register =
|
|||||||
let moves : register =
|
let moves : register =
|
||||||
Map.literal ([
|
Map.literal ([
|
||||||
("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address, (1,2)),
|
("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address, (1,2)),
|
||||||
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address, (0,3)),]);
|
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address, (0,3))]);
|
||||||
```
|
```
|
||||||
|
|
||||||
> The `Map.literal` predefined function builds a map from a list of
|
> The `Map.literal` predefined function builds a map from a list of
|
||||||
@ -377,8 +377,8 @@ example:
|
|||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
<!--Pascaligo-->
|
<!--Pascaligo-->
|
||||||
```pascaligo group=f
|
```pascaligo group=f
|
||||||
(*const my_balance : option (move) =
|
const my_balance : option (move) =
|
||||||
moves [("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address)] *)
|
moves [("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address)]
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--Cameligo-->
|
<!--Cameligo-->
|
||||||
@ -418,11 +418,12 @@ let force_access (key, moves : address * register) : move =
|
|||||||
```
|
```
|
||||||
|
|
||||||
<!--Reasonligo-->
|
<!--Reasonligo-->
|
||||||
```reasonlig group=f
|
```reasonligo group=f
|
||||||
let force_access : ((key, moves) : address * register) : move => {
|
let force_access = ((key, moves) : (address, register)) : move => {
|
||||||
switch (Map.find_opt key moves) with
|
switch (Map.find_opt (key, moves)) {
|
||||||
Some move -> move
|
| Some (move) => move
|
||||||
| None -> (failwith "No move." : move)
|
| None => failwith ("No move.") : move
|
||||||
|
}
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
@ -475,9 +476,8 @@ let assign (m : register) : register =
|
|||||||
```
|
```
|
||||||
|
|
||||||
> Notice the optional value `Some (4,9)` instead of `(4,9)`. If we had
|
> Notice the optional value `Some (4,9)` instead of `(4,9)`. If we had
|
||||||
> use `None` instead, that would have meant that the binding is only
|
> use `None` instead, that would have meant that the binding is
|
||||||
> defined on its key, but not its value. This encoding enables
|
> removed.
|
||||||
> partially defined bindings.
|
|
||||||
|
|
||||||
<!--Reasonligo-->
|
<!--Reasonligo-->
|
||||||
|
|
||||||
@ -492,9 +492,8 @@ let assign = (m : register) : register => {
|
|||||||
```
|
```
|
||||||
|
|
||||||
> Notice the optional value `Some (4,9)` instead of `(4,9)`. If we had
|
> Notice the optional value `Some (4,9)` instead of `(4,9)`. If we had
|
||||||
> use `None` instead, that would have meant that the binding is only
|
> use `None` instead, that would have meant that the binding is
|
||||||
> defined on its key, but not its value. This encoding enables
|
> removed.
|
||||||
> partially defined bindings.
|
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
@ -601,7 +600,7 @@ let map_op = (m : register) : register => {
|
|||||||
A *fold operation* is the most general of iterations. The iterated
|
A *fold operation* is the most general of iterations. The iterated
|
||||||
function takes two arguments: an *accumulator* and the structure
|
function takes two arguments: an *accumulator* and the structure
|
||||||
*element* at hand, with which it then produces a new accumulator. This
|
*element* at hand, with which it then produces a new accumulator. This
|
||||||
enables to have a partial result that becomes complete when the
|
enables having a partial result that becomes complete when the
|
||||||
traversal of the data structure is over.
|
traversal of the data structure is over.
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
@ -622,7 +621,7 @@ let fold_op (m : register) : register =
|
|||||||
|
|
||||||
<!--Reasonligo-->
|
<!--Reasonligo-->
|
||||||
```reasonligo group=f
|
```reasonligo group=f
|
||||||
let fold_op = (m: register): register => {
|
let fold_op = (m : register) : register => {
|
||||||
let aggregate = ((i,j): (int, (address, move))) => i + j[1][1];
|
let aggregate = ((i,j): (int, (address, move))) => i + j[1][1];
|
||||||
Map.fold (aggregate, m, 5);
|
Map.fold (aggregate, m, 5);
|
||||||
};
|
};
|
||||||
@ -703,7 +702,7 @@ let moves : register =
|
|||||||
let moves : register =
|
let moves : register =
|
||||||
Big_map.literal ([
|
Big_map.literal ([
|
||||||
("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address, (1,2)),
|
("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address, (1,2)),
|
||||||
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address, (0,3)),]);
|
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address, (0,3))]);
|
||||||
```
|
```
|
||||||
|
|
||||||
> The predefind function `Big_map.literal` constructs a big map from a
|
> The predefind function `Big_map.literal` constructs a big map from a
|
||||||
|
@ -8,15 +8,14 @@ LIGO offers three built-in numerical types: `int`, `nat` and `tez`.
|
|||||||
## Addition
|
## Addition
|
||||||
|
|
||||||
Addition in LIGO is accomplished by means of the `+` infix
|
Addition in LIGO is accomplished by means of the `+` infix
|
||||||
operator. Some type constraints apply, for example you ca not add a
|
operator. Some type constraints apply, for example you cannot add a
|
||||||
value of type `tez` to a value of type `nat`.
|
value of type `tez` to a value of type `nat`.
|
||||||
|
|
||||||
In the following example you can find a series of arithmetic
|
In the following example you can find a series of arithmetic
|
||||||
operations, including various numerical types. However, some bits
|
operations, including various numerical types. However, some bits
|
||||||
remain in comments because they would otherwise not compile because,
|
remain in comments as they would otherwise not compile, for example,
|
||||||
for example, adding a value of type `int` to a value of type `tez` is
|
adding a value of type `int` to a value of type `tez` is invalid. Note
|
||||||
invalid. Note that adding an integer to a natural number produces an
|
that adding an integer to a natural number produces an integer.
|
||||||
integer.
|
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
<!--Pascaligo-->
|
<!--Pascaligo-->
|
||||||
@ -115,7 +114,7 @@ let g : int = 1_000_000;
|
|||||||
|
|
||||||
## Subtraction
|
## Subtraction
|
||||||
|
|
||||||
Subtraction looks like as follows.
|
Subtraction looks as follows.
|
||||||
|
|
||||||
> ⚠️ Even when subtracting two `nats`, the result is an `int`
|
> ⚠️ Even when subtracting two `nats`, the result is an `int`
|
||||||
|
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
type coin = Head | Tail
|
||||||
|
|
||||||
|
let flip (c : coin) : coin =
|
||||||
|
match c with
|
||||||
|
Head -> Tail
|
||||||
|
| Tail -> Head
|
@ -0,0 +1,7 @@
|
|||||||
|
type coin = | Head | Tail;
|
||||||
|
|
||||||
|
let flip = (c : coin) : coin =>
|
||||||
|
switch (c) {
|
||||||
|
| Head => Tail
|
||||||
|
| Tail => Head
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user