catala/tests/func/good/closure_conversion.catala_en
2024-07-05 18:03:01 +02:00

112 lines
2.6 KiB
Plaintext

## Article
```catala
declaration scope S:
internal f content integer depends on y content integer
input x content boolean
output z content integer
scope S:
definition f of y equals if x then y else - y
definition z equals f of -1
```
```catala-test-inline
$ catala Typecheck --check-invariants
┌─[RESULT]─
│ All invariant checks passed
└─
┌─[RESULT]─
│ Typechecking successful!
└─
```
```catala-test-inline
$ catala Lcalc -O --closure-conversion
type Eoption = | ENone of unit | ESome of any
type S_in = { x_in: bool; }
type S = { z: integer; }
let topval closure_f1 : (closure_env, integer) → integer =
λ (env: closure_env) (y: integer) →
if (from_closure_env env).0 then y else - y
let scope S (S_in: S_in {x_in: bool}): S {z: integer} =
let get x : bool = S_in.x_in in
let set f : ((closure_env, integer) → integer, closure_env) =
(closure_f1, to_closure_env (x))
in
let set z : integer = f.0 f.1 -1 in
return { S z = z; }
```
```catala
declaration scope S2:
output dummy content boolean
input output cfun2 content decimal depends on x content integer
scope S2:
definition dummy equals false
declaration scope S2Use:
internal fun content decimal depends on y content integer
output o content (S2, S2)
declaration fun2 content decimal depends on y content integer equals y / 3
scope S2Use:
definition fun of y equals y / 2
definition o equals
(output of S2 with { -- cfun2: fun },
output of S2 with { -- cfun2: fun2 })
```
```catala-test-inline
$ catala Lcalc -O --closure-conversion -s S2Use
let scope S2Use
(S2Use_in: S2Use_in)
: S2Use {
o:
(S2 {
dummy: bool;
cfun2: ((closure_env, integer) → decimal, closure_env)
},
S2 {
dummy: bool;
cfun2: ((closure_env, integer) → decimal, closure_env)
})
}
=
let set fun : ((closure_env, integer) → decimal, closure_env) =
(closure_fun1, to_closure_env ())
in
let set o :
(S2 {
dummy: bool;
cfun2: ((closure_env, integer) → decimal, closure_env)
},
S2 {
dummy: bool;
cfun2: ((closure_env, integer) → decimal, closure_env)
}) =
(let result : S2 = S2 { S2_in cfun2_in = fun; } in
{ S2
dummy = result.dummy;
cfun2 = (closure_o1, to_closure_env (result));
},
let result : S2 =
S2 { S2_in cfun2_in = (closure_o3, to_closure_env ()); }
in
{ S2
dummy = result.dummy;
cfun2 = (closure_o2, to_closure_env (result));
})
in
return { S2Use o = o; }
```