@effekt-lang/effekt 0.10.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/effekt
CHANGED
|
Binary file
|
|
@@ -11,7 +11,7 @@ import io/error
|
|
|
11
11
|
/// Describes push streams by emitting values of type `A`.
|
|
12
12
|
effect emit[A](value: A): Unit
|
|
13
13
|
|
|
14
|
-
/// Describes pull streams by
|
|
14
|
+
/// Describes pull streams by reading values of type `A`.
|
|
15
15
|
///
|
|
16
16
|
/// The producer can decide to `stop` emitting values.
|
|
17
17
|
effect read[A](): A / stop
|
|
@@ -28,20 +28,14 @@ def for[A, R] { stream: () => R / emit[A] } { action: A => Unit }: R =
|
|
|
28
28
|
resume(action(value))
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
/// Like `for[A, R]`, but
|
|
32
|
-
///
|
|
33
|
-
///
|
|
31
|
+
/// Like `for[A, R]`, but ignores the result of the stream, and consequently
|
|
32
|
+
/// works for any type. Use this to annotate the type of stream elements
|
|
33
|
+
/// `A` without having to also annotate `R`.
|
|
34
34
|
///
|
|
35
35
|
/// e.g. for[Int] { prog() } { el => println(el) }
|
|
36
|
-
def for[A] { stream: () =>
|
|
37
|
-
for[A,
|
|
38
|
-
|
|
39
|
-
def continually[A] { action: () => A }: Nothing / emit[A] = {
|
|
40
|
-
def go(): Nothing = {
|
|
41
|
-
do emit(action())
|
|
42
|
-
go()
|
|
43
|
-
}
|
|
44
|
-
go()
|
|
36
|
+
def for[A] { stream: () => Any / emit[A] } { action: A => Unit }: Unit = {
|
|
37
|
+
for[A, Any]{stream}{action}
|
|
38
|
+
()
|
|
45
39
|
}
|
|
46
40
|
|
|
47
41
|
/// Turns a `list` into a producer of a push stream
|
|
@@ -91,23 +85,28 @@ def boundary[R] { program: () => R / stop }: Option[R] =
|
|
|
91
85
|
try {
|
|
92
86
|
Some(program())
|
|
93
87
|
} with stop {
|
|
94
|
-
|
|
88
|
+
None()
|
|
95
89
|
}
|
|
96
90
|
|
|
97
|
-
def
|
|
91
|
+
def boundary { program: () => Any / stop }: Unit = {
|
|
92
|
+
boundary[Any]{program}
|
|
93
|
+
()
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/// Run `program` forever until `stop` is thrown.
|
|
97
|
+
def exhaustively { program: () => Any / stop }: Unit =
|
|
98
98
|
try {
|
|
99
99
|
def go(): Unit = {
|
|
100
|
-
|
|
100
|
+
program()
|
|
101
101
|
go()
|
|
102
102
|
}
|
|
103
103
|
go()
|
|
104
104
|
} with stop {
|
|
105
|
-
|
|
105
|
+
()
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
|
|
109
|
-
|
|
110
|
-
|
|
109
|
+
/// In Effekt lower bounds are inclusive and upper bounds are exclusive
|
|
111
110
|
record Indexed[A](index: Int, value: A)
|
|
112
111
|
|
|
113
112
|
def range(lower: Int, upper: Int): Unit / emit[Int] =
|
|
@@ -137,7 +136,7 @@ def index[A, R] { stream: () => R / emit[A] }: R / emit[Indexed[A]] = {
|
|
|
137
136
|
}
|
|
138
137
|
|
|
139
138
|
/// If `number` is zero or negative it does nothing
|
|
140
|
-
def
|
|
139
|
+
def limit[A, R](number: Int) { stream: () => R / emit[A] }: R / { emit[A], stop } = {
|
|
141
140
|
if (number <= 0) do stop();
|
|
142
141
|
var i = 1;
|
|
143
142
|
try {
|
|
@@ -152,6 +151,13 @@ def take[A, R](number: Int) { stream: () => R / emit[A] }: R / { emit[A], stop }
|
|
|
152
151
|
}
|
|
153
152
|
}
|
|
154
153
|
|
|
154
|
+
/// If `number` is zero or negative it does nothing
|
|
155
|
+
def limit[A](number: Int) { stream: () => Any / emit[A] }: Unit / emit[A] =
|
|
156
|
+
boundary {
|
|
157
|
+
limit[A, Any](number){stream}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
|
|
155
161
|
/// If `number` is zero or negative it does nothing
|
|
156
162
|
def replicate[A](number: Int) { action: () => A }: Unit / emit[A] =
|
|
157
163
|
if (number > 0) {
|
|
@@ -170,8 +176,8 @@ def sum[R] { stream : () => R / emit[Int] }: (R, Int) = {
|
|
|
170
176
|
}
|
|
171
177
|
}
|
|
172
178
|
|
|
173
|
-
def sum { stream : () =>
|
|
174
|
-
sum[
|
|
179
|
+
def sum { stream : () => Any / emit[Int] }: Int =
|
|
180
|
+
sum[Any]{stream}.second
|
|
175
181
|
|
|
176
182
|
def collectList[A, R] { stream: () => R / emit[A] }: (R, List[A]) =
|
|
177
183
|
try {
|
|
@@ -181,8 +187,8 @@ def collectList[A, R] { stream: () => R / emit[A] }: (R, List[A]) =
|
|
|
181
187
|
(r, Cons(v, vs))
|
|
182
188
|
}
|
|
183
189
|
|
|
184
|
-
def collectList[A] { stream: () =>
|
|
185
|
-
collectList[A,
|
|
190
|
+
def collectList[A] { stream: () => Any / emit[A] }: List[A] =
|
|
191
|
+
collectList[A, Any]{stream}.second
|
|
186
192
|
|
|
187
193
|
def collectArray[A, R] { stream: () => R / emit[A] }: (R, Array[A]) = {
|
|
188
194
|
var i = 0
|
|
@@ -197,8 +203,8 @@ def collectArray[A, R] { stream: () => R / emit[A] }: (R, Array[A]) = {
|
|
|
197
203
|
}
|
|
198
204
|
}
|
|
199
205
|
|
|
200
|
-
def collectArray[A] { stream: () =>
|
|
201
|
-
collectArray[A,
|
|
206
|
+
def collectArray[A] { stream: () => Any / emit[A] }: Array[A] =
|
|
207
|
+
collectArray[A, Any]{stream}.second
|
|
202
208
|
|
|
203
209
|
def collectBytes[R] { stream: () => R / emit[Byte] }: (R, ByteArray) = {
|
|
204
210
|
var i = 0
|
|
@@ -213,10 +219,10 @@ def collectBytes[R] { stream: () => R / emit[Byte] }: (R, ByteArray) = {
|
|
|
213
219
|
}
|
|
214
220
|
}
|
|
215
221
|
|
|
216
|
-
def collectBytes { stream: () =>
|
|
217
|
-
collectBytes[
|
|
222
|
+
def collectBytes { stream: () => Any / emit[Byte] }: ByteArray =
|
|
223
|
+
collectBytes[Any]{stream}.second
|
|
218
224
|
|
|
219
|
-
def feed[T](list: List[T]) { reader: () =>
|
|
225
|
+
def feed[T, R](list: List[T]) { reader: () => R / read[T] }: R = {
|
|
220
226
|
var l = list
|
|
221
227
|
try {
|
|
222
228
|
reader()
|
|
@@ -232,14 +238,16 @@ def feed[T](list: List[T]) { reader: () => Unit / read[T] } = {
|
|
|
232
238
|
}
|
|
233
239
|
}
|
|
234
240
|
|
|
235
|
-
def feed[T](array: Array[T]) { reader: () =>
|
|
241
|
+
def feed[T, R](array: Array[T]) { reader: () => R / read[T] }: R = {
|
|
236
242
|
var i = 0
|
|
237
243
|
try {
|
|
238
244
|
reader()
|
|
239
245
|
} with read[T] {
|
|
240
246
|
resume {
|
|
241
247
|
if (i < array.size) {
|
|
242
|
-
|
|
248
|
+
val c = i
|
|
249
|
+
i = c + 1
|
|
250
|
+
array.unsafeGet(c)
|
|
243
251
|
} else {
|
|
244
252
|
do stop()
|
|
245
253
|
}
|
|
@@ -247,14 +255,16 @@ def feed[T](array: Array[T]) { reader: () => Unit / read[T] } = {
|
|
|
247
255
|
}
|
|
248
256
|
}
|
|
249
257
|
|
|
250
|
-
def feed(bytes: ByteArray) { reader: () =>
|
|
258
|
+
def feed[R](bytes: ByteArray) { reader: () => R / read[Byte] }: R = {
|
|
251
259
|
var i = 0
|
|
252
260
|
try {
|
|
253
261
|
reader()
|
|
254
262
|
} with read[Byte] {
|
|
255
263
|
resume {
|
|
256
264
|
if (i < bytes.size) {
|
|
257
|
-
|
|
265
|
+
val c = i
|
|
266
|
+
i = c + 1
|
|
267
|
+
bytes.unsafeGet(c)
|
|
258
268
|
} else {
|
|
259
269
|
do stop()
|
|
260
270
|
}
|
|
@@ -262,7 +272,7 @@ def feed(bytes: ByteArray) { reader: () => Unit / read[Byte] } = {
|
|
|
262
272
|
}
|
|
263
273
|
}
|
|
264
274
|
|
|
265
|
-
def source[A, R] { stream: () =>
|
|
275
|
+
def source[A, R] { stream: () => Any / emit[A] } { reader: () => R / read[A] }: R = {
|
|
266
276
|
var next = box { None() }
|
|
267
277
|
next = box {
|
|
268
278
|
try {
|
|
@@ -282,6 +292,21 @@ def source[A, R] { stream: () => Unit / emit[A] } { reader: () => R / read[A] }:
|
|
|
282
292
|
}
|
|
283
293
|
}
|
|
284
294
|
|
|
295
|
+
def source[A] { stream: () => Any / emit[A] } { reader: () => Any / read[A] }: Unit = {
|
|
296
|
+
source[A, Any]{stream}{reader}
|
|
297
|
+
()
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/// Combines two streams together producing a stream of pairs in lockstep.
|
|
301
|
+
/// Given two streams of length `n` and `m`, it produces a stream of length `min(n, m)`.
|
|
302
|
+
def zip[A, B] { stream1: () => Any / emit[A] } { stream2: () => Any / emit[B] } { action: (A, B) => Any }: Unit = {
|
|
303
|
+
with source[A] { stream1 }
|
|
304
|
+
with source[B] { stream2 }
|
|
305
|
+
|
|
306
|
+
exhaustively {
|
|
307
|
+
action(do read[A](), do read[B]())
|
|
308
|
+
}
|
|
309
|
+
}
|
|
285
310
|
|
|
286
311
|
def writeFile[R](path: String) { stream: () => R / emit[Byte] }: R / Exception[IOError] = {
|
|
287
312
|
|
|
@@ -407,13 +432,15 @@ def feed(string: String) { reader: () => Unit / read[Char] } =
|
|
|
407
432
|
|
|
408
433
|
def each(string: String): Unit / emit[Char] =
|
|
409
434
|
feed(string) {
|
|
410
|
-
exhaustively
|
|
435
|
+
exhaustively {
|
|
436
|
+
do emit[Char](do read[Char]())
|
|
437
|
+
}
|
|
411
438
|
}
|
|
412
439
|
|
|
413
440
|
def collectString[R] { stream: () => R / emit[Char] }: (R, String) = {
|
|
414
|
-
val (result, bytes) = collectBytes { encodeUTF8 { stream } }
|
|
441
|
+
val (result, bytes) = collectBytes[R] { encodeUTF8 { stream } }
|
|
415
442
|
(result, bytes.toString)
|
|
416
443
|
}
|
|
417
444
|
|
|
418
|
-
def collectString { stream: () =>
|
|
419
|
-
collectString[
|
|
445
|
+
def collectString { stream: () => Any / emit[Char] }: String =
|
|
446
|
+
collectString[Any]{stream}.second
|
|
@@ -113,22 +113,23 @@ function SHIFT(p, body, ks, k) {
|
|
|
113
113
|
cont = { stack: meta.stack, prompt: meta.prompt, backup: meta.arena.backup(), rest: cont }
|
|
114
114
|
meta = meta.rest
|
|
115
115
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
meta = { stack: toRewind.stack, prompt: toRewind.prompt, arena: toRewind.backup(), rest: meta }
|
|
121
|
-
toRewind = toRewind.rest
|
|
122
|
-
}
|
|
116
|
+
const k1 = meta.stack
|
|
117
|
+
meta.stack = null
|
|
118
|
+
return body(cont, meta, k1)
|
|
119
|
+
}
|
|
123
120
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
121
|
+
// Rewind stack `cont` back onto `k` :: `ks` and resume with c
|
|
122
|
+
function RESUME(cont, c, ks, k) {
|
|
123
|
+
let meta = { stack: k, prompt: ks.prompt, arena: ks.arena, rest: ks.rest }
|
|
124
|
+
let toRewind = cont
|
|
125
|
+
while (!!toRewind) {
|
|
126
|
+
meta = { stack: toRewind.stack, prompt: toRewind.prompt, arena: toRewind.backup(), rest: meta }
|
|
127
|
+
toRewind = toRewind.rest
|
|
127
128
|
}
|
|
128
129
|
|
|
129
|
-
|
|
130
|
+
const k1 = meta.stack // TODO instead copy meta here, like elsewhere?
|
|
130
131
|
meta.stack = null
|
|
131
|
-
return
|
|
132
|
+
return () => c(meta, k1)
|
|
132
133
|
}
|
|
133
134
|
|
|
134
135
|
function RUN_TOPLEVEL(comp) {
|
|
@@ -210,4 +211,4 @@ $effekt.run = RUN
|
|
|
210
211
|
*
|
|
211
212
|
* If a runtime is available, use `$effekt.run`, instead.
|
|
212
213
|
*/
|
|
213
|
-
$effekt.runToplevel = RUN_TOPLEVEL
|
|
214
|
+
$effekt.runToplevel = RUN_TOPLEVEL
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!doctype html><html lang=en><head><meta charset=utf-8><meta http-equiv=x-ua-compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><title>Eclipse Public License 2.0 (EPL) | The Eclipse Foundation</title><meta property="og:title" content="Eclipse Public License 2.0 (EPL) | The Eclipse Foundation"><meta name=twitter:title content="Eclipse Public License 2.0 (EPL) | The Eclipse Foundation"><meta name=description content="The Eclipse Foundation provides our global community of individuals and organisations with a mature, scalable, and business-friendly environment for open source …"><meta property="og:description" content="The Eclipse Foundation provides our global community of individuals and organisations with a mature, scalable, and business-friendly environment for open source …"><meta name=twitter:description content="The Eclipse Foundation provides our global community of individuals and organisations with a mature, scalable, and business-friendly environment for open source …"><meta name=author content="Wayne Beaton"><link href=/favicon.ico rel=icon type=image/x-icon><meta property="og:image" content="https://www.eclipse.org/images/logos/eclipse-foundation-400x400.png"><meta name=twitter:image content="https://www.eclipse.org/images/logos/eclipse-foundation-400x400.png"><meta name=twitter:card content="summary"><meta name=twitter:site content="@eclipsefdn"><meta name=twitter:creator content="@eclipsefdn"><meta property="og:url" content="https://www.eclipse.org/legal/epl-2.0/"><meta property="og:type" content="website"><meta property="og:site_name" content="Eclipse Foundation"><meta name=keywords content="epl,epl-2.0,legal,foundation,eclipse,eclipse public license,license,licenses"><meta name=generator content="Hugo 0.110.0"><link rel=canonical href=https://www.eclipse.org/legal/epl-2.0/><link rel=alternate href=/legal/epl-2.0/index.xml type=application/rss+xml title><link rel=stylesheet href="/public/css/styles.css?v=
|
|
1
|
+
<!doctype html><html lang=en><head><meta charset=utf-8><meta http-equiv=x-ua-compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><title>Eclipse Public License 2.0 (EPL) | The Eclipse Foundation</title><meta property="og:title" content="Eclipse Public License 2.0 (EPL) | The Eclipse Foundation"><meta name=twitter:title content="Eclipse Public License 2.0 (EPL) | The Eclipse Foundation"><meta name=description content="The Eclipse Foundation provides our global community of individuals and organisations with a mature, scalable, and business-friendly environment for open source …"><meta property="og:description" content="The Eclipse Foundation provides our global community of individuals and organisations with a mature, scalable, and business-friendly environment for open source …"><meta name=twitter:description content="The Eclipse Foundation provides our global community of individuals and organisations with a mature, scalable, and business-friendly environment for open source …"><meta name=author content="Wayne Beaton"><link href=/favicon.ico rel=icon type=image/x-icon><meta property="og:image" content="https://www.eclipse.org/images/logos/eclipse-foundation-400x400.png"><meta name=twitter:image content="https://www.eclipse.org/images/logos/eclipse-foundation-400x400.png"><meta name=twitter:card content="summary"><meta name=twitter:site content="@eclipsefdn"><meta name=twitter:creator content="@eclipsefdn"><meta property="og:url" content="https://www.eclipse.org/legal/epl-2.0/"><meta property="og:type" content="website"><meta property="og:site_name" content="Eclipse Foundation"><meta name=keywords content="epl,epl-2.0,legal,foundation,eclipse,eclipse public license,license,licenses"><meta name=generator content="Hugo 0.110.0"><link rel=canonical href=https://www.eclipse.org/legal/epl-2.0/><link rel=alternate href=/legal/epl-2.0/index.xml type=application/rss+xml title><link rel=stylesheet href="/public/css/styles.css?v=1733080574"><script>(function(e,t,n,s,o){e[s]=e[s]||[],e[s].push({"gtm.start":(new Date).getTime(),event:"gtm.js"});var a=t.getElementsByTagName(n)[0],i=t.createElement(n),r=s!="dataLayer"?"&l="+s:"";i.async=!0,i.src="https://www.googletagmanager.com/gtm.js?id="+o+r,a.parentNode.insertBefore(i,a)})(window,document,"script","dataLayer","GTM-5WLCZXC")</script><script>var tableClasses="table"</script><link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel=stylesheet type=text/css></head><body><noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-5WLCZXC" height=0 width=0 style=display:none;visibility:hidden></iframe></noscript><a class=sr-only href=#content>Skip to main content</a><header class="header-wrapper header-wrapper" id=header><div class=header-toolbar><div class=container><div class=header-toolbar-row><div class="toolbar-btn toolbar-search-btn dropdown"><button class=dropdown-toggle id=toolbar-search type=button data-toggle=dropdown tabindex=0 aria-label=Search>
|
|
2
2
|
<i class="fa fa-search fa-lg" aria-role=none></i></button><div class="toolbar-search-bar-wrapper dropdown-menu dropdown-menu-right" aria-labelledby=toolbar-search><form action=https://www.eclipse.org/home/search method=get><div class=search-bar><input class=search-bar-input name=q placeholder=Search>
|
|
3
3
|
<button>
|
|
4
4
|
<i class="fa fa-search" type=submit></i></button></div></form></div></div><div class="toolbar-btn toolbar-user-menu-btn dropdown"><button class=dropdown-toggle id=toolbar-user-menu type=button data-toggle=dropdown tabindex=0 aria-label="User Menu">
|
|
@@ -57,5 +57,5 @@ open source software collaboration and innovation.</p></div><div class=mega-menu
|
|
|
57
57
|
<i class="fa fa-linkedin fa-stack-1x fa-inverse" aria-hidden=true></i>
|
|
58
58
|
<span class=sr-only>Linkedin account</span></span></a></li></ul></div></div><div class="footer-sections row equal-height-md font-bold"><div class=col-md-15><div class=row><section id=footer-eclipse-foundation class="footer-section col-sm-8"><div class=menu-heading>Eclipse Foundation</div><ul class=nav><li><a href=https://www.eclipse.org/org/>About</a></li><li><a href=https://projects.eclipse.org/>Projects</a></li><li><a href=https://www.eclipse.org/collaborations/>Collaborations</a></li><li><a href=https://www.eclipse.org/membership/>Membership</a></li><li><a href=https://www.eclipse.org/sponsor/>Sponsor</a></li></ul></section><section id=footer-legal class="footer-section col-sm-8"><div class=menu-heading>Legal</div><ul class=nav><li><a href=https://www.eclipse.org/legal/privacy/>Privacy Policy</a></li><li><a href=https://www.eclipse.org/legal/terms-of-use/>Terms of Use</a></li><li><a href=https://www.eclipse.org/legal/compliance/>Compliance</a></li><li><a href=https://www.eclipse.org/org/documents/Community_Code_of_Conduct.php>Code of Conduct</a></li><li><a href=https://www.eclipse.org/legal/>Legal Resources</a></li><li><a class=toolbar-manage-cookies href=# onclick=event.preventDefault()>Manage Cookies</a></li></ul></section><section id=footer-more class="footer-section col-sm-8"><div class=menu-heading>More</div><ul class=nav><li><a href=https://www.eclipse.org/security/>Report a Vulnerability</a></li><li><a href=https://status.eclipse.org/>Service Status</a></li><li><a href=https://www.eclipse.org/org/foundation/contact.php>Contact Us</a></li><li><a href=https://www.eclipse.org/projects/support/>Support</a></li></ul></section></div></div><div id=footer-end class="footer-section col-md-8 col-md-offset-1 col-sm-24"><div class=footer-end-newsletter><form id=mc-embedded-subscribe-form action=https://eclipsecon.us6.list-manage.com/subscribe/post method=post novalidate target=_blank><label class=footer-end-newsletter-label for=email>Subscribe to our Newsletter</label><div class=footer-end-newsletter-input-wrapper><input class=footer-end-newsletter-input type=email id=email name=EMAIL autocomplete=email placeholder="Enter your email address"><div><i class="fa fa-solid fa-envelope fa-lg" aria-hidden=true></i></div></div><input type=hidden name=u value=eaf9e1f06f194eadc66788a85>
|
|
59
59
|
<input type=hidden name=id value=46e57eacf1>
|
|
60
|
-
<input id=mc-embedded-subscribe type=submit name=subscribe hidden></form></div></div></div><div class="col-sm-24 margin-top-20"><div class=row><div id=copyright class=col-md-16><p id=copyright-text>Copyright © Eclipse Foundation AISBL. All Rights Reserved.</p></div></div></div><a href=# class=scrollup>Back to the top</a></div></footer><div id=footer-js><script src="/public/js/main.js?v1.0?v=
|
|
60
|
+
<input id=mc-embedded-subscribe type=submit name=subscribe hidden></form></div></div></div><div class="col-sm-24 margin-top-20"><div class=row><div id=copyright class=col-md-16><p id=copyright-text>Copyright © Eclipse Foundation AISBL. All Rights Reserved.</p></div></div></div><a href=# class=scrollup>Back to the top</a></div></footer><div id=footer-js><script src="/public/js/main.js?v1.0?v=1733080574"></script>
|
|
61
61
|
<script>(function(){})(jQuery,document)</script></div></body></html>
|