@@ -45,7 +45,145 @@ There are 3 forms of valid type signatures in Nu:
45
45
- Basic: E.g. ` int ` , ` bool ` , ` string ` , etc.
46
46
- Compound:
47
47
- ` list<string> ` ,
48
- ` record<type: int, bar: string> `
48
+ ` record<type: int, bar: string> ` ,
49
+ ` table<name: string, age: int> `
50
+ - Sum types (aka type alternatives): E.g. ` oneof<int, string> `
51
+
52
+ ### List types
53
+
54
+ - ` list<something> ` - Read as ` list of elements of type something `
55
+
56
+ For example, ` list<int> ` would specify a list of integers:
57
+
58
+ ``` nu
59
+ def sum_two []: list<int> -> int { $in.0 + $in.1 }
60
+
61
+ [1 11 111 1111] | sum_two
62
+ # => 12
63
+
64
+ ["abc" "def" "ghi"] | sum_two
65
+ # error: command doesn't support list<string> input
66
+ ```
67
+
68
+ - ` list ` - If no element type is specified, this is equivalent to ` list<any> ` .
69
+
70
+ ``` nu
71
+ def second []: list -> any { $in.1 }
72
+
73
+ [1 11 111 1111] | second
74
+ # => 11
75
+
76
+ ["abc" "def" "ghi"] | second
77
+ # => def
78
+ ```
79
+
80
+ ### Record types
81
+
82
+ - ` record<key_name: value_type> ` - Read as ` record containing a key key_name with value of type value_type `
83
+
84
+ ``` nu
85
+ def greet [person: record<name: string>] {
86
+ $"Hello, ($person.name)!"
87
+ }
88
+
89
+ greet { name: Ellie }
90
+ # => Hello, Ellie!
91
+
92
+ greet "Who"
93
+ # error: a string is not a record
94
+
95
+ greet { given_name: Bob }
96
+ # error: the record is missing a "name" key
97
+
98
+ greet { name: [] }
99
+ # error: the record's "name" value can't be coerced to string
100
+
101
+ # The record may contain more keys besides the specified ones though:
102
+ greet { name: Bob, age: 32 }
103
+ # => Hello, Bob!
104
+ ```
105
+
106
+ We may also specify multiple keys that a record must posess as a comma separated ` name: value_type ` list. E.g.:
107
+
108
+ ``` nu
109
+ def greet [person: record<name: string, birthday: datetime, job: string>] {
110
+ print $"Hello, ($person.name) the ($person.job)!"
111
+ if ($person.birthday | format date "%m-%d") == (date now | format date "%m-%d") {
112
+ print "Happy birthday!"
113
+ }
114
+ }
115
+
116
+ greet { name: Bob, job: Builder, birthday: 1998-11-28 }
117
+ # => Hello, Bob the Builder!
118
+ ```
119
+
120
+ Similar to lists, ` record ` or ` record<> ` specifies a record with any keys (or even an empty record):
121
+
122
+ ``` nu
123
+ def first_key []: record -> string {
124
+ columns | first
125
+ }
126
+
127
+ { name: Ellie } | first_key
128
+ # => name
129
+
130
+ { given_name: Bob } | first_key
131
+ # => given_name
132
+
133
+ # this will pass type checking (but produce a runtime error)
134
+ {} | first_key
135
+ ```
136
+
137
+ ### Table types
138
+
139
+ - ` table<column_name: value_type> ` - Read as ` table containing a column column_name with values of type value_type `
140
+
141
+ Tables are just lists of records, so table types work very similarly to record types:
142
+
143
+ ``` nu
144
+ let data: table<date: datetime, temps: list<number>, condition: string> = [
145
+ [date temps condition ];
146
+ [2022-02-01T14:30:00+05:00, [38.24, 38.50, 37.99, 37.98, 39.10], 'sunny' ],
147
+ [2022-02-02T14:30:00+05:00, [35.24, 35.94, 34.91, 35.24, 36.65], 'sunny' ],
148
+ [2022-02-03T14:30:00+05:00, [35.17, 36.67, 34.42, 35.76, 36.52], 'cloudy' ],
149
+ [2022-02-04T14:30:00+05:00, [39.24, 40.94, 39.21, 38.99, 38.80], 'rain' ]
150
+ ]
151
+
152
+ def temp_avg [] : table<date: datetime, temps: list<number>> -> table<date: datetime, avg_temp: number> {
153
+ insert avg_temp {|record| $record.temps | math avg}
154
+ | reject temps
155
+ }
156
+
157
+ # Note that both the input and output table contain a column "condition", which
158
+ # is not mentioned in the type signature of temp_avg. This is fine.
159
+ $data | temp_avg
160
+ # => ╭───┬─────────────┬───────────┬──────────╮
161
+ # => │ # │ date │ condition │ avg_temp │
162
+ # => ├───┼─────────────┼───────────┼──────────┤
163
+ # => │ 0 │ 3 years ago │ sunny │ 38.36 │
164
+ # => │ 1 │ 3 years ago │ sunny │ 35.60 │
165
+ # => │ 2 │ 3 years ago │ cloudy │ 35.71 │
166
+ # => │ 3 │ 3 years ago │ rain │ 39.44 │
167
+ # => ╰───┴─────────────┴───────────┴──────────╯
168
+ ```
169
+
170
+ ### Sum types
171
+
172
+ - ` oneof<a, b, c> ` - Read: one of ` a ` , ` b ` or ` c `
173
+
174
+ Example:
175
+
176
+ ``` nu
177
+ def foo [
178
+ param: oneof<binary, string>
179
+ ] {
180
+ if ($param | describe) == "binary" {
181
+ $param | first 3
182
+ } else {
183
+ $param | str substring 0..<3
184
+ }
185
+ }
186
+ ```
49
187
50
188
## Custom command parameters and flags
51
189
0 commit comments