reflection¶

In [ ]:
//// test

open testing

reflection¶

get_union_fields¶

In [ ]:
inl get_union_fields forall union_type. () : list (string * union_type) =
    real
        real_core.union_to_record
            `union_type
            forall union_record_type. =>
                real_core.record_type_fold
                    fun acc key =>
                        forall value. =>
                            inl value =
                                typecase value with
                                | () => $'' : value
                                | _ =>
                                    backend_switch `value `({}) {
                                        Fsharp =
                                            (fun () =>
                                                $'Unchecked.defaultof<_>' : value
                                            ) : () -> value
                                        Python =
                                            (fun () =>
                                                $'None' : value
                                            ) : () -> value
                                    }
                            inl item = real_core.nominal_create `union_type (key, value)
                            inl key' = sm'_real.symbol_to_string `(`key)
                            (::) `(string * union_type) (key', item) acc
                    (Nil `(string * union_type))
                    `union_record_type
In [ ]:
//// test
///! fsharp
///! rust
///! typescript
///! python

get_union_fields ()
|> listm'.box
|> listm'.to_array'
|> a
|> am'.sort_by snd
|> fun (a x : _ int _) => x
|> _assert_eq' ;[ "Native", Native; "Wasm", Wasm; "Contract", Contract ]
.rs output:
{ name = __assert_eq'; actual = Array(MutCell([("Native", US0_0), ("Wasm", US0_1), ("Contract", US0_2)])); expected = Array(MutCell([("Native", US0_0), ("Wasm", US0_1), ("Contract", US0_2)])) }

.ts output:
{ name = __assert_eq'; actual = Native,US0_0,Wasm,US0_1,Contract,US0_2; expected = Native,US0_0,Wasm,US0_1,Contract,US0_2 }

.py output:
{ name = __assert_eq'; actual = [('Native', US0_0), ('Wasm', US0_1), ('Contract', US0_2)]; expected = [('Native', US0_0), ('Wasm', US0_1), ('Contract', US0_2)] }

.fsx output:
{ name = __assert_eq'; actual = [|struct ("Native", US0_0); struct ("Wasm", US0_1); struct ("Contract", US0_2)|]; expected = [|struct ("Native", US0_0); struct ("Wasm", US0_1); struct ("Contract", US0_2)|] }
In [ ]:
//// test
///! fsharp
///! rust
///! typescript
///! python

get_union_fields ()
|> listm'.box
|> listm'.to_array'
|> a
|> am'.sort_by snd
|> fun (a x : _ int _) => x
|> _assert_eq' ;[ "Some", Some 0i32; "None", None ]
.rs output:
{ name = __assert_eq'; actual = Array(MutCell([("Some", US0_0(0)), ("None", US0_1)])); expected = Array(MutCell([("Some", US0_0(0)), ("None", US0_1)])) }

.ts output:
{ name = __assert_eq'; actual = Some,US0_0 0,None,US0_1; expected = Some,US0_0 0,None,US0_1 }

.py output:
{ name = __assert_eq'; actual = [('Some', US0_0 0), ('None', US0_1)]; expected = [('Some', US0_0 0), ('None', US0_1)] }

.fsx output:
{ name = __assert_eq'; actual = [|struct ("Some", US0_0 0); struct ("None", US0_1)|]; expected = [|struct ("Some", US0_0 0); struct ("None", US0_1)|] }

get_union_fields_untag¶

In [ ]:
inl get_union_fields_untag forall union_type. () : list (string * union_type) =
    real
        real_core.union_to_record
            `union_type
            forall union_record_type. =>
                inl result =
                    real_core.record_type_fold_back
                        fun _key =>
                            forall value. (acc, (i : i32)) =>
                                inl key, item : (string * union_type) =
                                    real_core.union_untag `union_type i
                                        (fun key => forall value. =>
                                            inl key' = sm'_real.symbol_to_string `(`key)
                                            inl value =
                                                typecase value with
                                                | () => $'' : value
                                                | _ =>
                                                    backend_switch `value `({}) {
                                                        Fsharp =
                                                            (fun () =>
                                                                $'Unchecked.defaultof<_>' : value
                                                            ) : () -> value
                                                        Python =
                                                            (fun () =>
                                                                $'None' : value
                                                            ) : () -> value
                                                    }
                                            inl item = real_core.nominal_create `union_type (key, value)
                                            key', item
                                        )
                                        (fun _ =>
                                            failwith
                                                `(string * union_type)
                                                "reflection.get_union_fields_untag / invalid tag"
                                        )
                                (::) `(string * union_type) (key, item) acc, (+) `i32 i 1
                        `union_record_type
                        (Nil `(string * union_type), 0i32)
                inl result = fst `(list (string * union_type)) `i32 result
                listm.rev `(string * union_type) result
In [ ]:
//// test
///! fsharp
///! cuda
///! rust
///! typescript
///! python

get_union_fields_untag ()
|> _assert_eq' [ "Native", Native; "Wasm", Wasm; "Contract", Contract ]
.py output (Python):
{ name = __assert_eq'; actual = UH0_1(v0='Native', v1=US0_0(), v2=UH0_1(v0='Wasm', v1=US0_1(), v2=UH0_1(v0='Contract', v1=US0_2(), v2=UH0_0()))); expected = UH0_1(v0='Native', v1=US0_0(), v2=UH0_1(v0='Wasm', v1=US0_1(), v2=UH0_1(v0='Contract', v1=US0_2(), v2=UH0_0()))) }

.rs output:
{ name = __assert_eq'; actual = UH0_1("Native", US0_0, UH0_1("Wasm", US0_1, UH0_1("Contract", US0_2, UH0_0))); expected = UH0_1("Native", US0_0, UH0_1("Wasm", US0_1, UH0_1("Contract", US0_2, UH0_0))) }

.ts output:
{ name = __assert_eq'; actual = UH0_1 (Native, US0_0, UH0_1 (Wasm, US0_1, UH0_1 (Contract, US0_2, UH0_0))); expected = UH0_1 (Native, US0_0, UH0_1 (Wasm, US0_1, UH0_1 (Contract, US0_2, UH0_0))) }

.py output:
{ name = __assert_eq'; actual = UH0_1 ("Native", US0_0, UH0_1 ("Wasm", US0_1, UH0_1 ("Contract", US0_2, UH0_0))); expected = UH0_1 ("Native", US0_0, UH0_1 ("Wasm", US0_1, UH0_1 ("Contract", US0_2, UH0_0))) }

.fsx output:
{ name = __assert_eq'; actual = UH0_1 ("Native", US0_0, UH0_1 ("Wasm", US0_1, UH0_1 ("Contract", US0_2, UH0_0))); expected = UH0_1 ("Native", US0_0, UH0_1 ("Wasm", US0_1, UH0_1 ("Contract", US0_2, UH0_0))) }
In [ ]:
//// test
///! fsharp
///! cuda
///! rust
///! typescript
///! python

get_union_fields_untag ()
|> _assert_eq' [ "Some", Some (); "None", None ]
.py output (Python):
{ name = __assert_eq'; actual = UH0_1(v0='Some', v1=US0_0(), v2=UH0_1(v0='None', v1=US0_1(), v2=UH0_0())); expected = UH0_1(v0='Some', v1=US0_0(), v2=UH0_1(v0='None', v1=US0_1(), v2=UH0_0())) }

.rs output:
{ name = __assert_eq'; actual = UH0_1("Some", US0_0, UH0_1("None", US0_1, UH0_0)); expected = UH0_1("Some", US0_0, UH0_1("None", US0_1, UH0_0)) }

.ts output:
{ name = __assert_eq'; actual = UH0_1 (Some, US0_0, UH0_1 (None, US0_1, UH0_0)); expected = UH0_1 (Some, US0_0, UH0_1 (None, US0_1, UH0_0)) }

.py output:
{ name = __assert_eq'; actual = UH0_1 ("Some", US0_0, UH0_1 ("None", US0_1, UH0_0)); expected = UH0_1 ("Some", US0_0, UH0_1 ("None", US0_1, UH0_0)) }

.fsx output:
{ name = __assert_eq'; actual = UH0_1 ("Some", US0_0, UH0_1 ("None", US0_1, UH0_0)); expected = UH0_1 ("Some", US0_0, UH0_1 ("None", US0_1, UH0_0)) }

union_try_pick¶

In [ ]:
inl union_try_pick forall t. (key : string) : option t =
    real get_union_fields_untag `t ()
    ++ (
        real get_union_fields_untag `t ()
        |> listm.map fun key, x => key |> sm'.to_lower, x
    )
    |> listm'.try_pick fun key', x =>
        if key' = key
        then Some x
        else None
In [ ]:
//// test
///! fsharp

"wasm"
|> union_try_pick
|> _assert_eq (Some Wasm)

"Wasm"
|> union_try_pick
|> _assert_eq (Some Wasm)
{ name = __assert_eq; actual = US0_0 US1_1; expected = US0_0 US1_1 }
{ name = __assert_eq; actual = US0_0 US1_1; expected = US0_0 US1_1 }

union_to_string¶

In [ ]:
inl union_to_string forall t. (x : t) : string =
    real get_union_fields_untag `t ()
    |> listm'.try_pick fun key, x' =>
        if x' = x
        then Some key
        else
            inl has_case =
                real
                    real_core.union_to_record
                        `t
                        forall union_record_type. =>
                            real_core.record_type_fold_back
                                fun _key =>
                                    forall value. acc =>
                                        if acc
                                        then acc
                                        else
                                            typecase value with
                                            | () => false
                                            | _ => true
                                `union_record_type
                                false
            if has_case |> not
            then None
            else
                inl separator =
                    backend_switch {
                        Fsharp = fun () =>
                            run_target function
                                | Rust _ => fun () => join "("
                                | _ => fun () => join " "
                        Python = fun () => "("
                    }
                inl x' = x' |> sm'.format |> sm'.split separator |> am'.index_base 0
                if x |> sm'.format |> sm'.starts_with x'
                then Some key
                else None
    |> optionm.value
In [ ]:
//// test
///! fsharp
///! cuda
///! rust
///! typescript
///! python

Some true
|> union_to_string
|> _assert_eq' "Some"
.py output (Python):
{ name = __assert_eq'; actual = Some; expected = Some }

.rs output:
{ name = __assert_eq'; actual = Some; expected = Some }

.ts output:
{ name = __assert_eq'; actual = Some; expected = Some }

.py output:
{ name = __assert_eq'; actual = Some; expected = Some }

.fsx output:
{ name = __assert_eq'; actual = Some; expected = Some }

nameof¶

In [ ]:
inl nameof forall t. (x : t) : string =
    real
        real_core.record_type_fold_back
            fun key =>
                forall value. _ =>
                    sm'_real.symbol_to_string `(`key)
            `t
            ""
In [ ]:
//// test

{ test1 = ""; test2 = "" }
|> nameof
|> _assert_eq' "test1"
{ name = __assert_eq'; actual = test1; expected = test1 }

get_record_fields¶

In [ ]:
inl get_record_fields forall t u. (x : t) : list (string * u) =
    real
        real_core.record_type_fold_back
            fun key =>
                forall u'. acc =>
                    inl k = sm'_real.symbol_to_string `(`key)
                    inl v = x key
                    (::) `(string * u') (k, v) acc
            `t
            (Nil `(string * u))
In [ ]:
//// test

{ a = "1"; b = "2" }
|> get_record_fields
|> _assert_eq' [ "a", "1"; "b", "2" ]
{ name = __assert_eq'; actual = UH0_1 ("a", "1", UH0_1 ("b", "2", UH0_0)); expected = UH0_1 ("a", "1", UH0_1 ("b", "2", UH0_0)) }

get_functions_types¶

In [ ]:
inl get_functions_types forall t {record}. (fns : t) =
    real
        inl get_function_type forall t. =
            inl args forall t {record}. : list (string * string) =
                real_core.record_type_fold_back
                    fun key =>
                        forall v. acc =>
                            inl k = sm'_real.symbol_to_string `(`key)
                            inl v = $'"`v"' : string
                            (::) `(string * string) (k, v) acc
                    `t
                    (Nil `(string * string))

            typecase t with
            | ~t -> ~u => args `t, ($'"`u"' : string)

        real_core.record_type_fold_back
            fun key =>
                forall v. acc =>
                    inl k = sm'_real.symbol_to_string `(`key)
                    inl args, result = get_function_type `v
                    (::) `(string * (list (string * string) * string)) (k, (args, result)) acc
            `(`fns)
            (Nil `(string * (list (string * string) * string)))
    |> fun x => x : list (string * (list (string * string) * string))
In [ ]:
//// test

inl one ({ a } : { a : i32 }) : i32 = a + 1
inl two ({ a b } : { a : i32; b : i32 }) : i32 = a + b + 2
inl fns = { one two }

fns
|> get_functions_types
|> listm.map fun (name, args, result) => name, (args |> listm'.box |> listm'.to_array', result)
|> listm'.box
|> listm'.to_array'
|> sm'.format
|> _assert_eq' (
    [
        "one", ["a", "int32"], "int32"
        "two", ["a", "int32"; "b", "int32"], "int32"
    ]
    |> listm.map fun (name, args, result) => name, (args |> listm'.box |> listm'.to_array', result)
    |> listm'.box
    |> listm'.to_array'
    |> sm'.format
)
{ name = __assert_eq'; actual = [|struct ("one", [|struct ("a", "int32")|], "int32");
  struct ("two", [|struct ("a", "int32"); struct ("b", "int32")|], "int32")|]; expected = [|struct ("one", [|struct ("a", "int32")|], "int32");
  struct ("two", [|struct ("a", "int32"); struct ("b", "int32")|], "int32")|] }