roc/test/snapshots/let_polymorphism_complex.md
2025-11-23 01:22:01 -05:00

34 KiB

META

description=Complex let-polymorphism interactions
type=file

SOURCE

app [main] { pf: platform "../basic-cli/platform.roc" }

# Basic polymorphic values
num = 42
frac = 4.2
str = "hello"
bool = True

# Polymorphic empty collections
empty_list = []
empty_record = {}

# Using empty list in multiple contexts
int_list = [1, 2, 3]
str_list = ["a", "b", "c"]
bool_list = [True, False]

# Nested empty lists
nested_empty = [empty_list, empty_list, empty_list]
mixed_nested = [empty_list, [1, 2], empty_list, [3, 4]]

# Polymorphic record with empty list
poly_record = { items: empty_list, count: 0 }
use_poly_record1 = { items: [1, 2, 3], count: 0 }
use_poly_record2 = { items: ["x", "y", "z"], count: 0 }

# Complex nested structure with multiple polymorphic uses
base_config = {
    data: empty_list,
    metadata: {
        version: num,
        ratio: frac,
        description: str,
    },
}

# Different instantiations of base_config
config1 = {
    data: [1, 2, 3, 4, 5],
    metadata: {
        version: num,
        ratio: frac,
        description: str,
    },
    name: "integers",
}

config2 = { # Test comment 1
    data: ["apple", "banana", "cherry"], # Test comment 2
    metadata: { # Test comment 3
        version: num, # Test comment 4
        ratio: frac, # Test comment 5
        description: str, # Test comment 6
    }, # Test comment 7
    name: "fruits", # Test comment 8
} # Test comment 9

# Polymorphic function-like structures
make_container = |val| { value: val, wrapper: [val] }
container1 = make_container(num)
container2 = make_container(str)
container3 = make_container(frac)

# Deeply nested polymorphism
deep = {
    level1: {
        level2: {
            level3: {
                data: empty_list,
                value: num,
            },
            items: [num, num * 2, num * 3],
        },
        collection: empty_list,
    },
    results: [
        { data: [1], tag: "single" },
        { data: [1, 2], tag: "ints" },
        { data: [1, 2, 3], tag: "more" },
    ],
}

# Polymorphic values used in computations
compute1 = num + 10
compute2 = num * 2
compute3 = [num, num]
compute4 = { base: num, derived: [num, num + 1, num + 2] }

# Mixed polymorphic structures
mixed = {
    numbers: { value: num, list: [num, num], float: frac },
    strings: { value: str, list: [str, str] },
    empty_lists: {
        raw: empty_list,
        in_list: [empty_list],
        in_record: { data: empty_list },
    },
    computations: {
        from_num: num * 100,
        from_frac: frac * 10.0,
        list_from_num: [num, num, num],
    },
}

main = |_| {
    # Just type-check everything
    container1.value + 10
}

EXPECTED

NIL

PROBLEMS

NIL

TOKENS

KwApp,OpenSquare,LowerIdent,CloseSquare,OpenCurly,LowerIdent,OpColon,KwPlatform,StringStart,StringPart,StringEnd,CloseCurly,
LowerIdent,OpAssign,Int,
LowerIdent,OpAssign,Float,
LowerIdent,OpAssign,StringStart,StringPart,StringEnd,
LowerIdent,OpAssign,UpperIdent,
LowerIdent,OpAssign,OpenSquare,CloseSquare,
LowerIdent,OpAssign,OpenCurly,CloseCurly,
LowerIdent,OpAssign,OpenSquare,Int,Comma,Int,Comma,Int,CloseSquare,
LowerIdent,OpAssign,OpenSquare,StringStart,StringPart,StringEnd,Comma,StringStart,StringPart,StringEnd,Comma,StringStart,StringPart,StringEnd,CloseSquare,
LowerIdent,OpAssign,OpenSquare,UpperIdent,Comma,UpperIdent,CloseSquare,
LowerIdent,OpAssign,OpenSquare,LowerIdent,Comma,LowerIdent,Comma,LowerIdent,CloseSquare,
LowerIdent,OpAssign,OpenSquare,LowerIdent,Comma,OpenSquare,Int,Comma,Int,CloseSquare,Comma,LowerIdent,Comma,OpenSquare,Int,Comma,Int,CloseSquare,CloseSquare,
LowerIdent,OpAssign,OpenCurly,LowerIdent,OpColon,LowerIdent,Comma,LowerIdent,OpColon,Int,CloseCurly,
LowerIdent,OpAssign,OpenCurly,LowerIdent,OpColon,OpenSquare,Int,Comma,Int,Comma,Int,CloseSquare,Comma,LowerIdent,OpColon,Int,CloseCurly,
LowerIdent,OpAssign,OpenCurly,LowerIdent,OpColon,OpenSquare,StringStart,StringPart,StringEnd,Comma,StringStart,StringPart,StringEnd,Comma,StringStart,StringPart,StringEnd,CloseSquare,Comma,LowerIdent,OpColon,Int,CloseCurly,
LowerIdent,OpAssign,OpenCurly,
LowerIdent,OpColon,LowerIdent,Comma,
LowerIdent,OpColon,OpenCurly,
LowerIdent,OpColon,LowerIdent,Comma,
LowerIdent,OpColon,LowerIdent,Comma,
LowerIdent,OpColon,LowerIdent,Comma,
CloseCurly,Comma,
CloseCurly,
LowerIdent,OpAssign,OpenCurly,
LowerIdent,OpColon,OpenSquare,Int,Comma,Int,Comma,Int,Comma,Int,Comma,Int,CloseSquare,Comma,
LowerIdent,OpColon,OpenCurly,
LowerIdent,OpColon,LowerIdent,Comma,
LowerIdent,OpColon,LowerIdent,Comma,
LowerIdent,OpColon,LowerIdent,Comma,
CloseCurly,Comma,
LowerIdent,OpColon,StringStart,StringPart,StringEnd,Comma,
CloseCurly,
LowerIdent,OpAssign,OpenCurly,
LowerIdent,OpColon,OpenSquare,StringStart,StringPart,StringEnd,Comma,StringStart,StringPart,StringEnd,Comma,StringStart,StringPart,StringEnd,CloseSquare,Comma,
LowerIdent,OpColon,OpenCurly,
LowerIdent,OpColon,LowerIdent,Comma,
LowerIdent,OpColon,LowerIdent,Comma,
LowerIdent,OpColon,LowerIdent,Comma,
CloseCurly,Comma,
LowerIdent,OpColon,StringStart,StringPart,StringEnd,Comma,
CloseCurly,
LowerIdent,OpAssign,OpBar,LowerIdent,OpBar,OpenCurly,LowerIdent,OpColon,LowerIdent,Comma,LowerIdent,OpColon,OpenSquare,LowerIdent,CloseSquare,CloseCurly,
LowerIdent,OpAssign,LowerIdent,NoSpaceOpenRound,LowerIdent,CloseRound,
LowerIdent,OpAssign,LowerIdent,NoSpaceOpenRound,LowerIdent,CloseRound,
LowerIdent,OpAssign,LowerIdent,NoSpaceOpenRound,LowerIdent,CloseRound,
LowerIdent,OpAssign,OpenCurly,
LowerIdent,OpColon,OpenCurly,
LowerIdent,OpColon,OpenCurly,
LowerIdent,OpColon,OpenCurly,
LowerIdent,OpColon,LowerIdent,Comma,
LowerIdent,OpColon,LowerIdent,Comma,
CloseCurly,Comma,
LowerIdent,OpColon,OpenSquare,LowerIdent,Comma,LowerIdent,OpStar,Int,Comma,LowerIdent,OpStar,Int,CloseSquare,Comma,
CloseCurly,Comma,
LowerIdent,OpColon,LowerIdent,Comma,
CloseCurly,Comma,
LowerIdent,OpColon,OpenSquare,
OpenCurly,LowerIdent,OpColon,OpenSquare,Int,CloseSquare,Comma,LowerIdent,OpColon,StringStart,StringPart,StringEnd,CloseCurly,Comma,
OpenCurly,LowerIdent,OpColon,OpenSquare,Int,Comma,Int,CloseSquare,Comma,LowerIdent,OpColon,StringStart,StringPart,StringEnd,CloseCurly,Comma,
OpenCurly,LowerIdent,OpColon,OpenSquare,Int,Comma,Int,Comma,Int,CloseSquare,Comma,LowerIdent,OpColon,StringStart,StringPart,StringEnd,CloseCurly,Comma,
CloseSquare,Comma,
CloseCurly,
LowerIdent,OpAssign,LowerIdent,OpPlus,Int,
LowerIdent,OpAssign,LowerIdent,OpStar,Int,
LowerIdent,OpAssign,OpenSquare,LowerIdent,Comma,LowerIdent,CloseSquare,
LowerIdent,OpAssign,OpenCurly,LowerIdent,OpColon,LowerIdent,Comma,LowerIdent,OpColon,OpenSquare,LowerIdent,Comma,LowerIdent,OpPlus,Int,Comma,LowerIdent,OpPlus,Int,CloseSquare,CloseCurly,
LowerIdent,OpAssign,OpenCurly,
LowerIdent,OpColon,OpenCurly,LowerIdent,OpColon,LowerIdent,Comma,LowerIdent,OpColon,OpenSquare,LowerIdent,Comma,LowerIdent,CloseSquare,Comma,LowerIdent,OpColon,LowerIdent,CloseCurly,Comma,
LowerIdent,OpColon,OpenCurly,LowerIdent,OpColon,LowerIdent,Comma,LowerIdent,OpColon,OpenSquare,LowerIdent,Comma,LowerIdent,CloseSquare,CloseCurly,Comma,
LowerIdent,OpColon,OpenCurly,
LowerIdent,OpColon,LowerIdent,Comma,
LowerIdent,OpColon,OpenSquare,LowerIdent,CloseSquare,Comma,
LowerIdent,OpColon,OpenCurly,LowerIdent,OpColon,LowerIdent,CloseCurly,Comma,
CloseCurly,Comma,
LowerIdent,OpColon,OpenCurly,
LowerIdent,OpColon,LowerIdent,OpStar,Int,Comma,
LowerIdent,OpColon,LowerIdent,OpStar,Float,Comma,
LowerIdent,OpColon,OpenSquare,LowerIdent,Comma,LowerIdent,Comma,LowerIdent,CloseSquare,Comma,
CloseCurly,Comma,
CloseCurly,
LowerIdent,OpAssign,OpBar,Underscore,OpBar,OpenCurly,
LowerIdent,NoSpaceDotLowerIdent,OpPlus,Int,
CloseCurly,
EndOfFile,

PARSE

(file
	(app
		(provides
			(exposed-lower-ident
				(text "main")))
		(record-field (name "pf")
			(e-string
				(e-string-part (raw "../basic-cli/platform.roc"))))
		(packages
			(record-field (name "pf")
				(e-string
					(e-string-part (raw "../basic-cli/platform.roc"))))))
	(statements
		(s-decl
			(p-ident (raw "num"))
			(e-int (raw "42")))
		(s-decl
			(p-ident (raw "frac"))
			(e-frac (raw "4.2")))
		(s-decl
			(p-ident (raw "str"))
			(e-string
				(e-string-part (raw "hello"))))
		(s-decl
			(p-ident (raw "bool"))
			(e-tag (raw "True")))
		(s-decl
			(p-ident (raw "empty_list"))
			(e-list))
		(s-decl
			(p-ident (raw "empty_record"))
			(e-record))
		(s-decl
			(p-ident (raw "int_list"))
			(e-list
				(e-int (raw "1"))
				(e-int (raw "2"))
				(e-int (raw "3"))))
		(s-decl
			(p-ident (raw "str_list"))
			(e-list
				(e-string
					(e-string-part (raw "a")))
				(e-string
					(e-string-part (raw "b")))
				(e-string
					(e-string-part (raw "c")))))
		(s-decl
			(p-ident (raw "bool_list"))
			(e-list
				(e-tag (raw "True"))
				(e-tag (raw "False"))))
		(s-decl
			(p-ident (raw "nested_empty"))
			(e-list
				(e-ident (raw "empty_list"))
				(e-ident (raw "empty_list"))
				(e-ident (raw "empty_list"))))
		(s-decl
			(p-ident (raw "mixed_nested"))
			(e-list
				(e-ident (raw "empty_list"))
				(e-list
					(e-int (raw "1"))
					(e-int (raw "2")))
				(e-ident (raw "empty_list"))
				(e-list
					(e-int (raw "3"))
					(e-int (raw "4")))))
		(s-decl
			(p-ident (raw "poly_record"))
			(e-record
				(field (field "items")
					(e-ident (raw "empty_list")))
				(field (field "count")
					(e-int (raw "0")))))
		(s-decl
			(p-ident (raw "use_poly_record1"))
			(e-record
				(field (field "items")
					(e-list
						(e-int (raw "1"))
						(e-int (raw "2"))
						(e-int (raw "3"))))
				(field (field "count")
					(e-int (raw "0")))))
		(s-decl
			(p-ident (raw "use_poly_record2"))
			(e-record
				(field (field "items")
					(e-list
						(e-string
							(e-string-part (raw "x")))
						(e-string
							(e-string-part (raw "y")))
						(e-string
							(e-string-part (raw "z")))))
				(field (field "count")
					(e-int (raw "0")))))
		(s-decl
			(p-ident (raw "base_config"))
			(e-record
				(field (field "data")
					(e-ident (raw "empty_list")))
				(field (field "metadata")
					(e-record
						(field (field "version")
							(e-ident (raw "num")))
						(field (field "ratio")
							(e-ident (raw "frac")))
						(field (field "description")
							(e-ident (raw "str")))))))
		(s-decl
			(p-ident (raw "config1"))
			(e-record
				(field (field "data")
					(e-list
						(e-int (raw "1"))
						(e-int (raw "2"))
						(e-int (raw "3"))
						(e-int (raw "4"))
						(e-int (raw "5"))))
				(field (field "metadata")
					(e-record
						(field (field "version")
							(e-ident (raw "num")))
						(field (field "ratio")
							(e-ident (raw "frac")))
						(field (field "description")
							(e-ident (raw "str")))))
				(field (field "name")
					(e-string
						(e-string-part (raw "integers"))))))
		(s-decl
			(p-ident (raw "config2"))
			(e-record
				(field (field "data")
					(e-list
						(e-string
							(e-string-part (raw "apple")))
						(e-string
							(e-string-part (raw "banana")))
						(e-string
							(e-string-part (raw "cherry")))))
				(field (field "metadata")
					(e-record
						(field (field "version")
							(e-ident (raw "num")))
						(field (field "ratio")
							(e-ident (raw "frac")))
						(field (field "description")
							(e-ident (raw "str")))))
				(field (field "name")
					(e-string
						(e-string-part (raw "fruits"))))))
		(s-decl
			(p-ident (raw "make_container"))
			(e-lambda
				(args
					(p-ident (raw "val")))
				(e-record
					(field (field "value")
						(e-ident (raw "val")))
					(field (field "wrapper")
						(e-list
							(e-ident (raw "val")))))))
		(s-decl
			(p-ident (raw "container1"))
			(e-apply
				(e-ident (raw "make_container"))
				(e-ident (raw "num"))))
		(s-decl
			(p-ident (raw "container2"))
			(e-apply
				(e-ident (raw "make_container"))
				(e-ident (raw "str"))))
		(s-decl
			(p-ident (raw "container3"))
			(e-apply
				(e-ident (raw "make_container"))
				(e-ident (raw "frac"))))
		(s-decl
			(p-ident (raw "deep"))
			(e-record
				(field (field "level1")
					(e-record
						(field (field "level2")
							(e-record
								(field (field "level3")
									(e-record
										(field (field "data")
											(e-ident (raw "empty_list")))
										(field (field "value")
											(e-ident (raw "num")))))
								(field (field "items")
									(e-list
										(e-ident (raw "num"))
										(e-binop (op "*")
											(e-ident (raw "num"))
											(e-int (raw "2")))
										(e-binop (op "*")
											(e-ident (raw "num"))
											(e-int (raw "3")))))))
						(field (field "collection")
							(e-ident (raw "empty_list")))))
				(field (field "results")
					(e-list
						(e-record
							(field (field "data")
								(e-list
									(e-int (raw "1"))))
							(field (field "tag")
								(e-string
									(e-string-part (raw "single")))))
						(e-record
							(field (field "data")
								(e-list
									(e-int (raw "1"))
									(e-int (raw "2"))))
							(field (field "tag")
								(e-string
									(e-string-part (raw "ints")))))
						(e-record
							(field (field "data")
								(e-list
									(e-int (raw "1"))
									(e-int (raw "2"))
									(e-int (raw "3"))))
							(field (field "tag")
								(e-string
									(e-string-part (raw "more")))))))))
		(s-decl
			(p-ident (raw "compute1"))
			(e-binop (op "+")
				(e-ident (raw "num"))
				(e-int (raw "10"))))
		(s-decl
			(p-ident (raw "compute2"))
			(e-binop (op "*")
				(e-ident (raw "num"))
				(e-int (raw "2"))))
		(s-decl
			(p-ident (raw "compute3"))
			(e-list
				(e-ident (raw "num"))
				(e-ident (raw "num"))))
		(s-decl
			(p-ident (raw "compute4"))
			(e-record
				(field (field "base")
					(e-ident (raw "num")))
				(field (field "derived")
					(e-list
						(e-ident (raw "num"))
						(e-binop (op "+")
							(e-ident (raw "num"))
							(e-int (raw "1")))
						(e-binop (op "+")
							(e-ident (raw "num"))
							(e-int (raw "2")))))))
		(s-decl
			(p-ident (raw "mixed"))
			(e-record
				(field (field "numbers")
					(e-record
						(field (field "value")
							(e-ident (raw "num")))
						(field (field "list")
							(e-list
								(e-ident (raw "num"))
								(e-ident (raw "num"))))
						(field (field "float")
							(e-ident (raw "frac")))))
				(field (field "strings")
					(e-record
						(field (field "value")
							(e-ident (raw "str")))
						(field (field "list")
							(e-list
								(e-ident (raw "str"))
								(e-ident (raw "str"))))))
				(field (field "empty_lists")
					(e-record
						(field (field "raw")
							(e-ident (raw "empty_list")))
						(field (field "in_list")
							(e-list
								(e-ident (raw "empty_list"))))
						(field (field "in_record")
							(e-record
								(field (field "data")
									(e-ident (raw "empty_list")))))))
				(field (field "computations")
					(e-record
						(field (field "from_num")
							(e-binop (op "*")
								(e-ident (raw "num"))
								(e-int (raw "100"))))
						(field (field "from_frac")
							(e-binop (op "*")
								(e-ident (raw "frac"))
								(e-frac (raw "10.0"))))
						(field (field "list_from_num")
							(e-list
								(e-ident (raw "num"))
								(e-ident (raw "num"))
								(e-ident (raw "num"))))))))
		(s-decl
			(p-ident (raw "main"))
			(e-lambda
				(args
					(p-underscore))
				(e-block
					(statements
						(e-binop (op "+")
							(e-field-access
								(e-ident (raw "container1"))
								(e-ident (raw "value")))
							(e-int (raw "10")))))))))

FORMATTED

app [main] { pf: platform "../basic-cli/platform.roc" }

# Basic polymorphic values
num = 42
frac = 4.2
str = "hello"
bool = True

# Polymorphic empty collections
empty_list = []
empty_record = {}

# Using empty list in multiple contexts
int_list = [1, 2, 3]
str_list = ["a", "b", "c"]
bool_list = [True, False]

# Nested empty lists
nested_empty = [empty_list, empty_list, empty_list]
mixed_nested = [empty_list, [1, 2], empty_list, [3, 4]]

# Polymorphic record with empty list
poly_record = { items: empty_list, count: 0 }
use_poly_record1 = { items: [1, 2, 3], count: 0 }
use_poly_record2 = { items: ["x", "y", "z"], count: 0 }

# Complex nested structure with multiple polymorphic uses
base_config = {
	data: empty_list,
	metadata: {
		version: num,
		ratio: frac,
		description: str,
	},
}

# Different instantiations of base_config
config1 = {
	data: [1, 2, 3, 4, 5],
	metadata: {
		version: num,
		ratio: frac,
		description: str,
	},
	name: "integers",
}

config2 = { # Test comment 1
	data: ["apple", "banana", "cherry"], # Test comment 2
	metadata: { # Test comment 3
		version: num, # Test comment 4
		ratio: frac, # Test comment 5
		description: str, # Test comment 6
	}, # Test comment 7
	name: "fruits", # Test comment 8
} # Test comment 9

# Polymorphic function-like structures
make_container = |val| { value: val, wrapper: [val] }
container1 = make_container(num)
container2 = make_container(str)
container3 = make_container(frac)

# Deeply nested polymorphism
deep = {
	level1: {
		level2: {
			level3: {
				data: empty_list,
				value: num,
			},
			items: [num, num * 2, num * 3],
		},
		collection: empty_list,
	},
	results: [
		{ data: [1], tag: "single" },
		{ data: [1, 2], tag: "ints" },
		{ data: [1, 2, 3], tag: "more" },
	],
}

# Polymorphic values used in computations
compute1 = num + 10
compute2 = num * 2
compute3 = [num, num]
compute4 = { base: num, derived: [num, num + 1, num + 2] }

# Mixed polymorphic structures
mixed = {
	numbers: { value: num, list: [num, num], float: frac },
	strings: { value: str, list: [str, str] },
	empty_lists: {
		raw: empty_list,
		in_list: [empty_list],
		in_record: { data: empty_list },
	},
	computations: {
		from_num: num * 100,
		from_frac: frac * 10.0,
		list_from_num: [num, num, num],
	},
}

main = |_| {
	# Just type-check everything
	container1.value + 10
}

CANONICALIZE

(can-ir
	(d-let
		(p-assign (ident "num"))
		(e-num (value "42")))
	(d-let
		(p-assign (ident "frac"))
		(e-dec-small (numerator "42") (denominator-power-of-ten "1") (value "4.2")))
	(d-let
		(p-assign (ident "str"))
		(e-string
			(e-literal (string "hello"))))
	(d-let
		(p-assign (ident "bool"))
		(e-tag (name "True")))
	(d-let
		(p-assign (ident "empty_list"))
		(e-empty_list))
	(d-let
		(p-assign (ident "empty_record"))
		(e-empty_record))
	(d-let
		(p-assign (ident "int_list"))
		(e-list
			(elems
				(e-num (value "1"))
				(e-num (value "2"))
				(e-num (value "3")))))
	(d-let
		(p-assign (ident "str_list"))
		(e-list
			(elems
				(e-string
					(e-literal (string "a")))
				(e-string
					(e-literal (string "b")))
				(e-string
					(e-literal (string "c"))))))
	(d-let
		(p-assign (ident "bool_list"))
		(e-list
			(elems
				(e-tag (name "True"))
				(e-tag (name "False")))))
	(d-let
		(p-assign (ident "nested_empty"))
		(e-list
			(elems
				(e-lookup-local
					(p-assign (ident "empty_list")))
				(e-lookup-local
					(p-assign (ident "empty_list")))
				(e-lookup-local
					(p-assign (ident "empty_list"))))))
	(d-let
		(p-assign (ident "mixed_nested"))
		(e-list
			(elems
				(e-lookup-local
					(p-assign (ident "empty_list")))
				(e-list
					(elems
						(e-num (value "1"))
						(e-num (value "2"))))
				(e-lookup-local
					(p-assign (ident "empty_list")))
				(e-list
					(elems
						(e-num (value "3"))
						(e-num (value "4")))))))
	(d-let
		(p-assign (ident "poly_record"))
		(e-record
			(fields
				(field (name "items")
					(e-lookup-local
						(p-assign (ident "empty_list"))))
				(field (name "count")
					(e-num (value "0"))))))
	(d-let
		(p-assign (ident "use_poly_record1"))
		(e-record
			(fields
				(field (name "items")
					(e-list
						(elems
							(e-num (value "1"))
							(e-num (value "2"))
							(e-num (value "3")))))
				(field (name "count")
					(e-num (value "0"))))))
	(d-let
		(p-assign (ident "use_poly_record2"))
		(e-record
			(fields
				(field (name "items")
					(e-list
						(elems
							(e-string
								(e-literal (string "x")))
							(e-string
								(e-literal (string "y")))
							(e-string
								(e-literal (string "z"))))))
				(field (name "count")
					(e-num (value "0"))))))
	(d-let
		(p-assign (ident "base_config"))
		(e-record
			(fields
				(field (name "data")
					(e-lookup-local
						(p-assign (ident "empty_list"))))
				(field (name "metadata")
					(e-record
						(fields
							(field (name "version")
								(e-lookup-local
									(p-assign (ident "num"))))
							(field (name "ratio")
								(e-lookup-local
									(p-assign (ident "frac"))))
							(field (name "description")
								(e-lookup-local
									(p-assign (ident "str"))))))))))
	(d-let
		(p-assign (ident "config1"))
		(e-record
			(fields
				(field (name "data")
					(e-list
						(elems
							(e-num (value "1"))
							(e-num (value "2"))
							(e-num (value "3"))
							(e-num (value "4"))
							(e-num (value "5")))))
				(field (name "metadata")
					(e-record
						(fields
							(field (name "version")
								(e-lookup-local
									(p-assign (ident "num"))))
							(field (name "ratio")
								(e-lookup-local
									(p-assign (ident "frac"))))
							(field (name "description")
								(e-lookup-local
									(p-assign (ident "str")))))))
				(field (name "name")
					(e-string
						(e-literal (string "integers")))))))
	(d-let
		(p-assign (ident "config2"))
		(e-record
			(fields
				(field (name "data")
					(e-list
						(elems
							(e-string
								(e-literal (string "apple")))
							(e-string
								(e-literal (string "banana")))
							(e-string
								(e-literal (string "cherry"))))))
				(field (name "metadata")
					(e-record
						(fields
							(field (name "version")
								(e-lookup-local
									(p-assign (ident "num"))))
							(field (name "ratio")
								(e-lookup-local
									(p-assign (ident "frac"))))
							(field (name "description")
								(e-lookup-local
									(p-assign (ident "str")))))))
				(field (name "name")
					(e-string
						(e-literal (string "fruits")))))))
	(d-let
		(p-assign (ident "make_container"))
		(e-lambda
			(args
				(p-assign (ident "val")))
			(e-record
				(fields
					(field (name "value")
						(e-lookup-local
							(p-assign (ident "val"))))
					(field (name "wrapper")
						(e-list
							(elems
								(e-lookup-local
									(p-assign (ident "val"))))))))))
	(d-let
		(p-assign (ident "container1"))
		(e-call
			(e-lookup-local
				(p-assign (ident "make_container")))
			(e-lookup-local
				(p-assign (ident "num")))))
	(d-let
		(p-assign (ident "container2"))
		(e-call
			(e-lookup-local
				(p-assign (ident "make_container")))
			(e-lookup-local
				(p-assign (ident "str")))))
	(d-let
		(p-assign (ident "container3"))
		(e-call
			(e-lookup-local
				(p-assign (ident "make_container")))
			(e-lookup-local
				(p-assign (ident "frac")))))
	(d-let
		(p-assign (ident "deep"))
		(e-record
			(fields
				(field (name "level1")
					(e-record
						(fields
							(field (name "level2")
								(e-record
									(fields
										(field (name "level3")
											(e-record
												(fields
													(field (name "data")
														(e-lookup-local
															(p-assign (ident "empty_list"))))
													(field (name "value")
														(e-lookup-local
															(p-assign (ident "num")))))))
										(field (name "items")
											(e-list
												(elems
													(e-lookup-local
														(p-assign (ident "num")))
													(e-binop (op "mul")
														(e-lookup-local
															(p-assign (ident "num")))
														(e-num (value "2")))
													(e-binop (op "mul")
														(e-lookup-local
															(p-assign (ident "num")))
														(e-num (value "3")))))))))
							(field (name "collection")
								(e-lookup-local
									(p-assign (ident "empty_list")))))))
				(field (name "results")
					(e-list
						(elems
							(e-record
								(fields
									(field (name "data")
										(e-list
											(elems
												(e-num (value "1")))))
									(field (name "tag")
										(e-string
											(e-literal (string "single"))))))
							(e-record
								(fields
									(field (name "data")
										(e-list
											(elems
												(e-num (value "1"))
												(e-num (value "2")))))
									(field (name "tag")
										(e-string
											(e-literal (string "ints"))))))
							(e-record
								(fields
									(field (name "data")
										(e-list
											(elems
												(e-num (value "1"))
												(e-num (value "2"))
												(e-num (value "3")))))
									(field (name "tag")
										(e-string
											(e-literal (string "more"))))))))))))
	(d-let
		(p-assign (ident "compute1"))
		(e-binop (op "add")
			(e-lookup-local
				(p-assign (ident "num")))
			(e-num (value "10"))))
	(d-let
		(p-assign (ident "compute2"))
		(e-binop (op "mul")
			(e-lookup-local
				(p-assign (ident "num")))
			(e-num (value "2"))))
	(d-let
		(p-assign (ident "compute3"))
		(e-list
			(elems
				(e-lookup-local
					(p-assign (ident "num")))
				(e-lookup-local
					(p-assign (ident "num"))))))
	(d-let
		(p-assign (ident "compute4"))
		(e-record
			(fields
				(field (name "base")
					(e-lookup-local
						(p-assign (ident "num"))))
				(field (name "derived")
					(e-list
						(elems
							(e-lookup-local
								(p-assign (ident "num")))
							(e-binop (op "add")
								(e-lookup-local
									(p-assign (ident "num")))
								(e-num (value "1")))
							(e-binop (op "add")
								(e-lookup-local
									(p-assign (ident "num")))
								(e-num (value "2")))))))))
	(d-let
		(p-assign (ident "mixed"))
		(e-record
			(fields
				(field (name "numbers")
					(e-record
						(fields
							(field (name "value")
								(e-lookup-local
									(p-assign (ident "num"))))
							(field (name "list")
								(e-list
									(elems
										(e-lookup-local
											(p-assign (ident "num")))
										(e-lookup-local
											(p-assign (ident "num"))))))
							(field (name "float")
								(e-lookup-local
									(p-assign (ident "frac")))))))
				(field (name "strings")
					(e-record
						(fields
							(field (name "value")
								(e-lookup-local
									(p-assign (ident "str"))))
							(field (name "list")
								(e-list
									(elems
										(e-lookup-local
											(p-assign (ident "str")))
										(e-lookup-local
											(p-assign (ident "str")))))))))
				(field (name "empty_lists")
					(e-record
						(fields
							(field (name "raw")
								(e-lookup-local
									(p-assign (ident "empty_list"))))
							(field (name "in_list")
								(e-list
									(elems
										(e-lookup-local
											(p-assign (ident "empty_list"))))))
							(field (name "in_record")
								(e-record
									(fields
										(field (name "data")
											(e-lookup-local
												(p-assign (ident "empty_list"))))))))))
				(field (name "computations")
					(e-record
						(fields
							(field (name "from_num")
								(e-binop (op "mul")
									(e-lookup-local
										(p-assign (ident "num")))
									(e-num (value "100"))))
							(field (name "from_frac")
								(e-binop (op "mul")
									(e-lookup-local
										(p-assign (ident "frac")))
									(e-dec-small (numerator "100") (denominator-power-of-ten "1") (value "10"))))
							(field (name "list_from_num")
								(e-list
									(elems
										(e-lookup-local
											(p-assign (ident "num")))
										(e-lookup-local
											(p-assign (ident "num")))
										(e-lookup-local
											(p-assign (ident "num"))))))))))))
	(d-let
		(p-assign (ident "main"))
		(e-closure
			(captures
				(capture (ident "container1")))
			(e-lambda
				(args
					(p-underscore))
				(e-block
					(e-binop (op "add")
						(e-dot-access (field "value")
							(receiver
								(e-lookup-local
									(p-assign (ident "container1")))))
						(e-num (value "10"))))))))

TYPES

(inferred-types
	(defs
		(patt (type "a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
		(patt (type "a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
		(patt (type "Str"))
		(patt (type "[True]_others"))
		(patt (type "List(_a)"))
		(patt (type "{}"))
		(patt (type "List(a) where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
		(patt (type "List(Str)"))
		(patt (type "List([True, False]_others)"))
		(patt (type "List(List(_a))"))
		(patt (type "List(List(a)) where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
		(patt (type "{ count: a, items: List(_b) } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
		(patt (type "{ count: a, items: List(b) } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))
		(patt (type "{ count: a, items: List(Str) } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
		(patt (type "{ data: List(_a), metadata: { description: Str, ratio: b, version: c } } where [b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]), c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)])]"))
		(patt (type "{ data: List(a), metadata: { description: Str, ratio: b, version: c }, name: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]), c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)])]"))
		(patt (type "{ data: List(Str), metadata: { description: Str, ratio: a, version: b }, name: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))
		(patt (type "a -> { value: a, wrapper: List(a) }"))
		(patt (type "{ value: a, wrapper: List(a) } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
		(patt (type "{ value: Str, wrapper: List(Str) }"))
		(patt (type "{ value: a, wrapper: List(a) } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
		(patt (type "{ level1: { collection: List(_a), level2: { items: List(b), level3: { data: List(_c), value: d } } }, results: List({ data: List(e), tag: Str }) } where [b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]), d.from_numeral : Numeral -> Try(d, [InvalidNumeral(Str)]), e.from_numeral : Numeral -> Try(e, [InvalidNumeral(Str)])]"))
		(patt (type "a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
		(patt (type "a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
		(patt (type "List(a) where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
		(patt (type "{ base: a, derived: List(b) } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))
		(patt (type "{ computations: { from_frac: a, from_num: b, list_from_num: List(c) }, empty_lists: { in_list: List(List(_d)), in_record: { data: List(_e) }, raw: List(_f) }, numbers: { float: g, list: List(h), value: i }, strings: { list: List(Str), value: Str } } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]), c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)]), g.from_numeral : Numeral -> Try(g, [InvalidNumeral(Str)]), h.from_numeral : Numeral -> Try(h, [InvalidNumeral(Str)]), i.from_numeral : Numeral -> Try(i, [InvalidNumeral(Str)])]"))
		(patt (type "_arg -> a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]")))
	(expressions
		(expr (type "a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
		(expr (type "a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
		(expr (type "Str"))
		(expr (type "[True]_others"))
		(expr (type "List(_a)"))
		(expr (type "{}"))
		(expr (type "List(a) where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
		(expr (type "List(Str)"))
		(expr (type "List([True, False]_others)"))
		(expr (type "List(List(_a))"))
		(expr (type "List(List(a)) where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
		(expr (type "{ count: a, items: List(_b) } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
		(expr (type "{ count: a, items: List(b) } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))
		(expr (type "{ count: a, items: List(Str) } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
		(expr (type "{ data: List(_a), metadata: { description: Str, ratio: b, version: c } } where [b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]), c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)])]"))
		(expr (type "{ data: List(a), metadata: { description: Str, ratio: b, version: c }, name: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]), c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)])]"))
		(expr (type "{ data: List(Str), metadata: { description: Str, ratio: a, version: b }, name: Str } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))
		(expr (type "a -> { value: a, wrapper: List(a) }"))
		(expr (type "{ value: a, wrapper: List(a) } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
		(expr (type "{ value: Str, wrapper: List(Str) }"))
		(expr (type "{ value: a, wrapper: List(a) } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
		(expr (type "{ level1: { collection: List(_a), level2: { items: List(b), level3: { data: List(_c), value: d } } }, results: List({ data: List(e), tag: Str }) } where [b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]), d.from_numeral : Numeral -> Try(d, [InvalidNumeral(Str)]), e.from_numeral : Numeral -> Try(e, [InvalidNumeral(Str)])]"))
		(expr (type "a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
		(expr (type "a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
		(expr (type "List(a) where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
		(expr (type "{ base: a, derived: List(b) } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)])]"))
		(expr (type "{ computations: { from_frac: a, from_num: b, list_from_num: List(c) }, empty_lists: { in_list: List(List(_d)), in_record: { data: List(_e) }, raw: List(_f) }, numbers: { float: g, list: List(h), value: i }, strings: { list: List(Str), value: Str } } where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]), b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]), c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)]), g.from_numeral : Numeral -> Try(g, [InvalidNumeral(Str)]), h.from_numeral : Numeral -> Try(h, [InvalidNumeral(Str)]), i.from_numeral : Numeral -> Try(i, [InvalidNumeral(Str)])]"))
		(expr (type "_arg -> a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))))