File: vim9_generic_function_example_list.vim

package info (click to toggle)
vim 2%3A9.1.2103-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 93,456 kB
  • sloc: ansic: 433,730; cpp: 6,399; makefile: 4,597; sh: 2,397; java: 2,312; xml: 2,099; python: 1,595; perl: 1,419; awk: 730; lisp: 501; cs: 458; objc: 369; sed: 8; csh: 6; haskell: 1
file content (215 lines) | stat: -rw-r--r-- 4,690 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
vim9script
# VIM_TEST_SETUP let g:vimsyn_folding = "cfi"
# VIM_TEST_SETUP setl fdc=2 fdl=99 fdm=syntax
# VIM_TEST_SETUP hi link vim9DefTypeParam Todo
# See: https://github.com/vim/vim/pull/17313#issuecomment-3046696820 (Aliaksei Budavei)


# See https://github.com/vim/vim/pull/16604#issuecomment-265202845 .
export interface Listable
    def Cons<E>(_: E): Listable
    def Reverse<E>(): Listable
    def Rest(): Listable
    def First<E>(): E
    def empty(): bool
    def len(): number
    def string(): string
endinterface

enum EmptyList implements Listable
    INSTANCE

    def Cons<E>(value: E): Listable
	return List.new<E>(value)
    enddef

    def Reverse<E>(): Listable
	return this
    enddef

    def Rest(): Listable
	return this
    enddef

    def First<E>(): E
	return null
    enddef

    def empty(): bool
	return true
    enddef

    def len(): number
	return 0
    enddef

    def string(): string
	return '[]'
    enddef
endenum

class List implements Listable
    const _value: any
    const _size: number
    var _next: Listable

    def new<E>(value: E)
	this._value = value
	this._size = 1
	this._next = EmptyList.INSTANCE
    enddef

    def _newCons<E>(value: E, size: number)
	this._value = value
	this._size = size
    enddef

    def Cons<E>(value: E): Listable
	const list: List = List._newCons<E>(value, (this._size + 1))
	list._next = this
	return list
    enddef

    def Reverse<E>(): Listable
	var result: Listable = List.new<E>(this.First<E>())
	var list: Listable = this.Rest()

	while !list.empty()
	    result = result.Cons<E>(list.First<E>())
	    list = list.Rest()
	endwhile

	return result
    enddef

    def Rest(): Listable
	return this._next
    enddef

    def First<E>(): E
	return this._value
    enddef

    def empty(): bool
	return (this._size == 0)
    enddef

    def len(): number
	return this._size
    enddef

    def string(): string
	if this.empty()
	    return '[]'
	endif

	var text: string = '[' .. string(this.First<any>()) .. ', '
	var list: Listable = this.Rest()

	while !list.empty()
	    text ..= string(list.First<any>()) .. ', '
	    list = list.Rest()
	endwhile

	return strpart(text, 0, (strlen(text) - 2)) .. ']'
    enddef
endclass

export def MakeEmptyList(): Listable
    return EmptyList.INSTANCE
enddef

export def MakeList<E>(value: E): Listable
    return List.new<E>(value)
enddef

export def Map<T, U>(listable: Listable, Mapper: func(T): U): Listable
    var result: Listable = EmptyList.INSTANCE
    var list: Listable = listable

    while !list.empty()
	result = result.Cons<U>(Mapper(list.First<T>()))
	list = list.Rest()
    endwhile

    return result.Reverse<U>()
enddef

export def Filter<T>(listable: Listable, Predicate: func(T): bool): Listable
    var result: Listable = EmptyList.INSTANCE
    var list: Listable = listable

    while !list.empty()
	if Predicate(list.First<T>())
	    result = result.Cons<T>(list.First<T>())
	endif

	list = list.Rest()
    endwhile

    return result.Reverse<T>()
enddef

############################################################

echo MakeEmptyList()

const listX: Listable = MakeEmptyList()
    .Cons<number>(0).Cons<number>(1).Cons<number>(2).Cons<number>(3)
const listY: Listable = MakeList<number>(0)
    .Cons<number>(1).Cons<number>(2).Cons<number>(3)
echo listX == listY
echo listX
echo listX.Reverse<number>()
echo MakeEmptyList().Reverse<any>()
echo Filter<number>(listX, (value: number) => value % 2 != 0)
echo Map<number, string>(listX, (value: number) => nr2char((value + 60), 1))

echo 4 listX.len() listY.len()
echo listX
echo listY

const list3X: Listable = listX.Rest()
const list3Y: Listable = listY.Rest()
echo 3 list3X.len() list3Y.len()
echo list3X
echo list3Y

const list2X: Listable = list3X.Rest()
const list2Y: Listable = list3Y.Rest()
echo 2 list2X.len() list2Y.len()
echo list2X
echo list2Y

const list1X: Listable = list2X.Rest()
const list1Y: Listable = list2Y.Rest()
echo 1 list1X.len() list1Y.len()
echo list1X
echo list1Y

const list0X: Listable = list1X.Rest()
const list0Y: Listable = list1Y.Rest()
echo 0 list0X.len() list0Y.len()
echo list0X
echo list0Y

const list0X_: Listable = list0X.Rest()
const list0Y_: Listable = list0Y.Rest()
echo 0 list0X_.len() list0Y_.len()
echo list0X_
echo list0Y_

const list0X__: Listable = list0X_.Rest()
const list0Y__: Listable = list0Y_.Rest()
echo 0 list0X__.len() list0Y__.len()
echo list0X__
echo list0Y__


const listZ: Listable = MakeList<Listable>(MakeList<number>(-1))
const listZZ: Listable = listZ.Cons<Listable>(MakeList<number>(0))
    .Cons<Listable>(MakeList<number>(1))
    .Cons<Listable>(MakeList<number>(2))
    .Cons<Listable>(MakeList<number>(3))
echo listZZ