Merge branch 'interop-doc' into 'dev'
Interop docs See merge request ligolang/ligo!537
This commit is contained in:
commit
7f32937d6d
730
gitlab-pages/docs/advanced/interop.md
Normal file
730
gitlab-pages/docs/advanced/interop.md
Normal file
@ -0,0 +1,730 @@
|
||||
---
|
||||
id: interop
|
||||
title: Interop
|
||||
---
|
||||
|
||||
import Syntax from '@theme/Syntax';
|
||||
|
||||
LIGO can work together with other smart contract languages on Tezos. However
|
||||
data structures might have different representations in Michelson and not
|
||||
correctly match the standard LIGO types.
|
||||
|
||||
## Michelson types and annotations
|
||||
Michelson types consist of `or`'s and `pair`'s, combined with field annotations.
|
||||
Field annotations add contraints on a Michelson type, for example a pair of
|
||||
`(pair (int %foo) (string %bar))` will only work with the exact equivalence or
|
||||
the same type without the field annotations.
|
||||
|
||||
To clarify:
|
||||
|
||||
```michelson
|
||||
(pair (int %foo) (string %bar))
|
||||
````
|
||||
|
||||
works with
|
||||
|
||||
```michelson
|
||||
(pair (int %foo) (string %bar))
|
||||
```
|
||||
|
||||
works with
|
||||
|
||||
```michelson
|
||||
(pair int string)
|
||||
```
|
||||
|
||||
works not with
|
||||
|
||||
```michelson
|
||||
(pair (int %bar) (string %foo))
|
||||
```
|
||||
|
||||
works not with
|
||||
|
||||
```michelson
|
||||
(pair (string %bar) (int %foo))
|
||||
```
|
||||
|
||||
:::info
|
||||
In the case of annotated entrypoints - the annotated `or` tree directly under
|
||||
`parameter` in a contract - you should annotations, as otherwise it would
|
||||
become unclear which entrypoint you are referring to.
|
||||
:::
|
||||
|
||||
## Entrypoints and annotations
|
||||
It's possible for a contract to have multiple entrypoints, which translates in
|
||||
LIGO to a `parameter` with a variant type as shown here:
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo
|
||||
type storage is int
|
||||
|
||||
type parameter is
|
||||
| Left of int
|
||||
| Right of int
|
||||
|
||||
function main (const p: parameter; const x: storage): (list(operation) * storage) is
|
||||
((nil: list(operation)), case p of
|
||||
| Left(i) -> x - i
|
||||
| Right(i) -> x + i
|
||||
end)
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
```cameligo
|
||||
type storage = int
|
||||
|
||||
type parameter =
|
||||
| Left of int
|
||||
| Right of int
|
||||
|
||||
let main ((p, x): (parameter * storage)): (operation list * storage) =
|
||||
(([]: operation list), (match p with
|
||||
| Left i -> x - i
|
||||
| Right i -> x + i
|
||||
))
|
||||
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo
|
||||
type storage = int
|
||||
|
||||
type parameter =
|
||||
| Left(int)
|
||||
| Right(int)
|
||||
|
||||
let main = ((p, x): (parameter, storage)): (list(operation), storage) => {
|
||||
([]: list(operation), (switch(p) {
|
||||
| Left(i) => x - i
|
||||
| Right(i) => x + i
|
||||
}))
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
This contract can be called by another contract, like this one:
|
||||
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo group=get_entrypoint_opt
|
||||
type storage is int
|
||||
|
||||
type parameter is int
|
||||
|
||||
type x is Left of int
|
||||
|
||||
function main (const p: parameter; const s: storage): (list(operation) * storage) is block {
|
||||
const contract: contract(x) =
|
||||
case (Tezos.get_entrypoint_opt("%left", ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx":address)): option(contract(x))) of
|
||||
| Some (c) -> c
|
||||
| None -> (failwith("not a correct contract") : contract(x))
|
||||
end;
|
||||
|
||||
const result: (list(operation) * storage) = ((list [Tezos.transaction(Left(2), 2mutez, contract)]: list(operation)), s)
|
||||
} with result
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
```cameligo group=get_entrypoint_opt
|
||||
type storage = int
|
||||
|
||||
type parameter = int
|
||||
|
||||
type x = Left of int
|
||||
|
||||
let main (p, s: parameter * storage): operation list * storage = (
|
||||
let contract: x contract =
|
||||
match ((Tezos.get_entrypoint_opt "%left" ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address)): x contract option) with
|
||||
| Some c -> c
|
||||
| None -> (failwith "contract does not match": x contract)
|
||||
in
|
||||
(([
|
||||
Tezos.transaction (Left 2) 2mutez contract;
|
||||
]: operation list), s)
|
||||
)
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo group=get_entrypoint_opt
|
||||
type storage = int;
|
||||
|
||||
type parameter = int;
|
||||
|
||||
type x = Left(int);
|
||||
|
||||
let main = ((p, s): (parameter, storage)): (list(operation), storage) => {
|
||||
let contract: contract(x) =
|
||||
switch (Tezos.get_entrypoint_opt("%left", ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address)): option(contract(x))) {
|
||||
| Some c => c
|
||||
| None => (failwith ("contract does not match"): contract(x))
|
||||
};
|
||||
([
|
||||
Tezos.transaction(Left(2), 2mutez, contract)
|
||||
]: list(operation), s);
|
||||
};
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
Notice how we directly use the `%left` entrypoint without mentioning the
|
||||
`%right` entrypoint. This is done with the help of annotations. Without
|
||||
annotations it wouldn't be clear what our `int` would be referring to.
|
||||
|
||||
This currently only works for `or`'s or variant types in LIGO.
|
||||
|
||||
## Interop with Michelson
|
||||
To interop with existing Michelson code or for compatibility with certain
|
||||
development tooling, LIGO has two special interop types: `michelson_or` and
|
||||
`michelson_pair`. These types give the flexibility to model the exact Michelson
|
||||
output, including field annotations.
|
||||
|
||||
Take for example the following Michelson type that we want to interop with:
|
||||
|
||||
```michelson
|
||||
(or
|
||||
(unit %z)
|
||||
(or %other
|
||||
(unit %y)
|
||||
(pair %other
|
||||
(string %x)
|
||||
(pair %other
|
||||
(int %w)
|
||||
(nat %v)))))
|
||||
```
|
||||
|
||||
To reproduce this type we can use the following LIGO code:
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo
|
||||
type w_and_v is michelson_pair(int, "w", nat, "v")
|
||||
type x_and is michelson_pair(string, "x", w_and_v, "other")
|
||||
type y_or is michelson_or(unit, "y", x_and, "other")
|
||||
type z_or is michelson_or(unit, "z", y_or, "other")
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
```cameligo
|
||||
type w_and_v = (int, "w", nat, "v") michelson_pair
|
||||
type x_and = (string, "x", w_and_v, "other") michelson_pair
|
||||
type y_or = (unit, "y", x_and, "other") michelson_or
|
||||
type z_or = (unit, "z", y_or, "other") michelson_or
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo
|
||||
type w_and_v = michelson_pair(int, "w", nat, "v")
|
||||
type x_and = michelson_pair(string, "x", w_and_v, "other")
|
||||
type y_or = michelson_or(unit, "y", x_and, "other")
|
||||
type z_or = michelson_or(unit, "z", y_or, "other")
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
If you don't want to have an annotation, you need to provide an empty string.
|
||||
|
||||
:::info
|
||||
Alternatively, if annotations are not important you can also use plain tuples
|
||||
for pair's instead. Plain tuples don't have any annotations.
|
||||
:::
|
||||
|
||||
To use variables of type `michelson_or` you have to use `M_left` and `M_right`.
|
||||
`M_left` picks the left `or` case while `M_right` picks the right `or` case.
|
||||
For `michelson_pair` you need to use tuples.
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo
|
||||
const z: z_or = (M_left (unit) : z_or);
|
||||
|
||||
const y_1: y_or = (M_left (unit): y_or);
|
||||
const y: z_or = (M_right (y_1) : z_or);
|
||||
|
||||
const x_pair: x_and = ("foo", (2, 3n));
|
||||
const x_1: y_or = (M_right (x_pair): y_or);
|
||||
const x: z_or = (M_right (y_1) : z_or);
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
```cameligo
|
||||
let z: z_or = (M_left (unit) : z_or)
|
||||
|
||||
let y_1: y_or = (M_left (unit): y_or)
|
||||
let y: z_or = (M_right (y_1) : z_or)
|
||||
|
||||
let x_pair: x_and = ("foo", (2, 3n))
|
||||
let x_1: y_or = (M_right (x_pair): y_or)
|
||||
let x: z_or = (M_right (y_1) : z_or)
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo
|
||||
let z: z_or = (M_left (unit) : z_or)
|
||||
|
||||
let y_1: y_or = (M_left (unit): y_or)
|
||||
let y: z_or = (M_right (y_1) : z_or)
|
||||
|
||||
let x_pair: x_and = ("foo", (2, 3n))
|
||||
let x_1: y_or = (M_right (x_pair): y_or)
|
||||
let x: z_or = (M_right (y_1) : z_or)
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
## Helper functions
|
||||
Converting between different LIGO types and data structures can happen in two
|
||||
ways. The first way is to use the provided layout conversion functions, and the
|
||||
second way is to handle the layout conversion manually.
|
||||
|
||||
:::info
|
||||
In both cases it will increase the size of the smart contract and the
|
||||
conversion will happen when running the smart contract.
|
||||
:::
|
||||
|
||||
### Converting left combed Michelson data structures
|
||||
Here's an example of a left combed Michelson data structure using pairs:
|
||||
|
||||
```michelson
|
||||
(pair %other
|
||||
(pair %other
|
||||
(string %s)
|
||||
(int %w)
|
||||
)
|
||||
(nat %v)
|
||||
)
|
||||
```
|
||||
|
||||
Which could respond with the following record type:
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo
|
||||
type l_record is record [
|
||||
s: string;
|
||||
w: int;
|
||||
v: nat
|
||||
]
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
```cameligo
|
||||
type l_record = {
|
||||
s: string;
|
||||
w: int;
|
||||
v: nat
|
||||
}
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo
|
||||
type l_record = {
|
||||
s: string,
|
||||
w: int,
|
||||
v: nat
|
||||
}
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
If we want to convert from the Michelson type to our record type and vice
|
||||
versa, we can use the following code:
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo
|
||||
type michelson is michelson_pair_left_comb(l_record)
|
||||
|
||||
function of_michelson (const f: michelson) : l_record is
|
||||
block {
|
||||
const p: l_record = Layout.convert_from_left_comb(f)
|
||||
}
|
||||
with p
|
||||
|
||||
function to_michelson (const f: l_record) : michelson is
|
||||
block {
|
||||
const p: michelson = Layout.convert_to_left_comb ((f: l_record))
|
||||
}
|
||||
with p
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
```cameligo
|
||||
type michelson = l_record michelson_pair_left_comb
|
||||
|
||||
let of_michelson (f: michelson) : l_record =
|
||||
let p: l_record = Layout.convert_from_left_comb f in
|
||||
p
|
||||
|
||||
let to_michelson (f: l_record) : michelson =
|
||||
let p = Layout.convert_to_left_comb (f: l_record) in
|
||||
p
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo
|
||||
type michelson = michelson_pair_left_comb(l_record);
|
||||
|
||||
let of_michelson = (f: michelson) : l_record => {
|
||||
let p: l_record = Layout.convert_from_left_comb(f);
|
||||
p
|
||||
};
|
||||
|
||||
let to_michelson = (f: l_record) : michelson => {
|
||||
let p = Layout.convert_to_left_comb(f: l_record);
|
||||
p
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
In the case of a left combed Michelson `or` data structure, that you want to
|
||||
translate to a variant, you can use the `michelson_or_left_comb` type.
|
||||
|
||||
For example:
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo
|
||||
type vari is
|
||||
| Foo of int
|
||||
| Bar of nat
|
||||
| Other of bool
|
||||
|
||||
type r is michelson_or_left_comb(vari)
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
```cameligo
|
||||
type vari =
|
||||
| Foo of int
|
||||
| Bar of nat
|
||||
| Other of bool
|
||||
|
||||
type r = vari michelson_or_left_comb
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo
|
||||
type vari =
|
||||
| Foo(int)
|
||||
| Bar(nat)
|
||||
| Other(bool)
|
||||
|
||||
type r = michelson_or_left_comb(vari)
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
And then use these types in `Layout.convert_from_left_comb` or
|
||||
`Layout.convert_to_left_comb`, similar to the `pair`s example above, like this:
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo
|
||||
function of_michelson_or (const f: r) : vari is
|
||||
block {
|
||||
const p: vari = Layout.convert_from_left_comb(f)
|
||||
}
|
||||
with p
|
||||
|
||||
function to_michelson_or (const f: vari) : r is
|
||||
block {
|
||||
const p: r = Layout.convert_to_left_comb((f: vari))
|
||||
}
|
||||
with p
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
```cameligo
|
||||
let of_michelson_or (f: r) : vari =
|
||||
let p: vari = Layout.convert_from_left_comb f in
|
||||
p
|
||||
|
||||
let to_michelson_or (f: vari) : r =
|
||||
let p = Layout.convert_to_left_comb (f: vari) in
|
||||
p
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo
|
||||
let of_michelson_or = (f: r) : vari => {
|
||||
let p: vari = Layout.convert_from_left_comb(f);
|
||||
p
|
||||
};
|
||||
|
||||
let to_michelson_or = (f: vari) : r => {
|
||||
let p = Layout.convert_to_left_comb(f: vari);
|
||||
p
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
### Converting right combed Michelson data structures
|
||||
|
||||
In the case of right combed data structures, like:
|
||||
|
||||
```michelson
|
||||
(pair %other
|
||||
(string %s)
|
||||
(pair %other
|
||||
(int %w)
|
||||
(nat %v)
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
you can almost use the same code as that for the left combed data structures,
|
||||
but with `michelson_or_right_comb`, `michelson_pair_right_comb`,
|
||||
`Layout.convert_from_right_comb`, and `Layout.convert_to_left_comb`
|
||||
respectively.
|
||||
|
||||
### Manual data structure conversion
|
||||
If you want to get your hands dirty, it's also possible to do manual data
|
||||
structure conversion.
|
||||
|
||||
The following code can be used as inspiration:
|
||||
|
||||
<Syntax syntax="pascaligo">
|
||||
|
||||
```pascaligo group=helper_functions
|
||||
type z_to_v is
|
||||
| Z
|
||||
| Y
|
||||
| X
|
||||
| W
|
||||
| V
|
||||
|
||||
type w_or_v is michelson_or(unit, "w", unit, "v")
|
||||
type x_or is michelson_or(unit, "x", w_or_v, "other")
|
||||
type y_or is michelson_or(unit, "y", x_or, "other")
|
||||
type z_or is michelson_or(unit, "z", y_or, "other")
|
||||
|
||||
type test is record [
|
||||
z: string;
|
||||
y: int;
|
||||
x: string;
|
||||
w: bool;
|
||||
v: int;
|
||||
]
|
||||
|
||||
function make_concrete_sum (const r: z_to_v) : z_or is block {
|
||||
const z: z_or = (M_left (unit) : z_or);
|
||||
|
||||
const y_1: y_or = (M_left (unit): y_or);
|
||||
const y: z_or = (M_right (y_1) : z_or);
|
||||
|
||||
const x_2: x_or = (M_left (unit): x_or);
|
||||
const x_1: y_or = (M_right (x_2): y_or);
|
||||
const x: z_or = (M_right (x_1) : z_or);
|
||||
|
||||
const w_3: w_or_v = (M_left (unit): w_or_v);
|
||||
const w_2: x_or = (M_right (w_3): x_or);
|
||||
const w_1: y_or = (M_right (w_2): y_or);
|
||||
const w: z_or = (M_right (w_1) : z_or);
|
||||
|
||||
const v_3: w_or_v = (M_right (unit): w_or_v);
|
||||
const v_2: x_or = (M_right (v_3): x_or);
|
||||
const v_1: y_or = (M_right (v_2): y_or);
|
||||
const v: z_or = (M_right (v_1) : z_or);
|
||||
}
|
||||
with (case r of
|
||||
| Z -> z
|
||||
| Y -> y
|
||||
| X -> x
|
||||
| W -> w
|
||||
| V -> v
|
||||
end)
|
||||
|
||||
|
||||
function make_concrete_record (const r: test) : (string * int * string * bool * int) is
|
||||
(r.z, r.y, r.x, r.w, r.v)
|
||||
|
||||
function make_abstract_sum (const z_or: z_or) : z_to_v is
|
||||
(case z_or of
|
||||
| M_left (n) -> Z
|
||||
| M_right (y_or) ->
|
||||
(case y_or of
|
||||
| M_left (n) -> Y
|
||||
| M_right (x_or) ->
|
||||
(case x_or of
|
||||
| M_left (n) -> X
|
||||
| M_right (w_or) ->
|
||||
(case (w_or) of
|
||||
| M_left (n) -> W
|
||||
| M_right (n) -> V
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
function make_abstract_record (const z: string; const y: int; const x: string; const w: bool; const v: int) : test is
|
||||
record [ z = z; y = y; x = x; w = w; v = v ]
|
||||
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
|
||||
<Syntax syntax="cameligo">
|
||||
|
||||
```cameligo group=helper_functions
|
||||
type z_to_v =
|
||||
| Z
|
||||
| Y
|
||||
| X
|
||||
| W
|
||||
| V
|
||||
|
||||
type w_or_v = (unit, "w", unit, "v") michelson_or
|
||||
type x_or = (unit, "x", w_or_v, "other") michelson_or
|
||||
type y_or = (unit, "y", x_or, "other") michelson_or
|
||||
type z_or = (unit, "z", y_or, "other") michelson_or
|
||||
|
||||
type test = {
|
||||
z: string;
|
||||
y: int;
|
||||
x: string;
|
||||
w: bool;
|
||||
v: int;
|
||||
}
|
||||
|
||||
let make_concrete_sum (r: z_to_v) : z_or =
|
||||
match r with
|
||||
| Z -> (M_left (unit) : z_or)
|
||||
| Y -> (M_right (M_left (unit): y_or) : z_or )
|
||||
| X -> (M_right (M_right (M_left (unit): x_or): y_or) : z_or )
|
||||
| W -> (M_right (M_right (M_right (M_left (unit): w_or_v): x_or): y_or) : z_or )
|
||||
| V -> (M_right (M_right (M_right (M_right (unit): w_or_v): x_or): y_or) : z_or )
|
||||
|
||||
let make_concrete_record (r: test) : (string * int * string * bool * int) =
|
||||
(r.z, r.y, r.x, r.w, r.v)
|
||||
|
||||
let make_abstract_sum (z_or: z_or) : z_to_v =
|
||||
match z_or with
|
||||
| M_left n -> Z
|
||||
| M_right y_or ->
|
||||
(match y_or with
|
||||
| M_left n -> Y
|
||||
| M_right x_or -> (
|
||||
match x_or with
|
||||
| M_left n -> X
|
||||
| M_right w_or -> (
|
||||
match w_or with
|
||||
| M_left n -> W
|
||||
| M_right n -> V)))
|
||||
|
||||
|
||||
let make_abstract_record (z: string) (y: int) (x: string) (w: bool) (v: int) : test =
|
||||
{ z = z; y = y; x = x; w = w; v = v }
|
||||
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
<Syntax syntax="reasonligo">
|
||||
|
||||
```reasonligo group=helper_functions
|
||||
type z_to_v =
|
||||
| Z
|
||||
| Y
|
||||
| X
|
||||
| W
|
||||
| V
|
||||
|
||||
type w_or_v = michelson_or(unit, "w", unit, "v")
|
||||
type x_or = michelson_or(unit, "x", w_or_v, "other")
|
||||
type y_or = michelson_or(unit, "y", x_or, "other")
|
||||
type z_or = michelson_or(unit, "z", y_or, "other")
|
||||
|
||||
type test = {
|
||||
z: string,
|
||||
y: int,
|
||||
x: string,
|
||||
w: bool,
|
||||
v: int
|
||||
}
|
||||
|
||||
let make_concrete_sum = (r: z_to_v) : z_or =>
|
||||
switch(r){
|
||||
| Z => (M_left (unit) : z_or)
|
||||
| Y => (M_right (M_left (unit): y_or) : z_or )
|
||||
| X => (M_right (M_right (M_left (unit): x_or): y_or) : z_or )
|
||||
| W => (M_right (M_right (M_right (M_left (unit): w_or_v): x_or): y_or) : z_or )
|
||||
| V => (M_right (M_right (M_right (M_right (unit): w_or_v): x_or): y_or) : z_or )
|
||||
}
|
||||
|
||||
let make_concrete_record = (r: test) : (string, int, string, bool, int) =>
|
||||
(r.z, r.y, r.x, r.w, r.v)
|
||||
|
||||
let make_abstract_sum = (z_or: z_or) : z_to_v =>
|
||||
switch (z_or) {
|
||||
| M_left n => Z
|
||||
| M_right y_or => (
|
||||
switch (y_or) {
|
||||
| M_left n => Y
|
||||
| M_right x_or => (
|
||||
switch (x_or) {
|
||||
| M_left n => X
|
||||
| M_right w_or => (
|
||||
switch (w_or) {
|
||||
| M_left n => W
|
||||
| M_right n => V
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
let make_abstract_record = (z: string, y: int, x: string, w: bool, v: int) : test =>
|
||||
{ z : z, y, x, w, v }
|
||||
|
||||
```
|
||||
|
||||
</Syntax>
|
||||
|
||||
## Amendment
|
||||
With the upcoming 007 amendment to Tezos this will change though, and also
|
||||
`pair`'s can be ordered differently.
|
@ -20,7 +20,8 @@
|
||||
"advanced/include",
|
||||
"advanced/first-contract",
|
||||
"advanced/michelson-and-ligo",
|
||||
"advanced/inline"
|
||||
"advanced/inline",
|
||||
"advanced/interop"
|
||||
],
|
||||
"Reference": [
|
||||
"api/cli-commands",
|
||||
|
@ -123,6 +123,7 @@ let md_files = [
|
||||
"/gitlab-pages/docs/advanced/entrypoints-contracts.md";
|
||||
"/gitlab-pages/docs/advanced/timestamps-addresses.md";
|
||||
"/gitlab-pages/docs/advanced/inline.md";
|
||||
"/gitlab-pages/docs/advanced/interop.md";
|
||||
"/gitlab-pages/docs/api/cli-commands.md";
|
||||
"/gitlab-pages/docs/api/cheat-sheet.md";
|
||||
"/gitlab-pages/docs/reference/toplevel.md";
|
||||
|
Loading…
Reference in New Issue
Block a user