File: LazyArray.k

package info (click to toggle)
kaya 0.2.0-6
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 3,012 kB
  • ctags: 1,307
  • sloc: cpp: 6,691; haskell: 4,833; sh: 2,868; yacc: 768; makefile: 700; perl: 87
file content (115 lines) | stat: -rw-r--r-- 2,838 bytes parent folder | download | duplicates (5)
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
/** -*-C-*-ish
    Kaya standard library
    Copyright (C) 2004, 2005 Edwin Brady

    This file is distributed under the terms of the GNU Lesser General
    Public Licence. See COPYING for licence.
*/

module LazyArray;

import Prelude;

"Lazy Arrays of element type <em>val</em>."
// init is the initial state, used for a reset.

abstract data LazyArray<state,val>(state init, state current, 
				  (state,val)(state) next, Bool(state) end,
				  Void(state) cleanup,
				  Void(state) reset);

Exception EndOfArray = Exception("Reached the end of the Array",140);

"Default Array cleanup function."
public Void defaultCleanup(state s)
{
    // Do nothing
}

"Default Array reset function."
public Void defaultReset(state s)
{
    // Do nothing
}

"Create a lazy Array.
<em>state</em> is the type holding the state which is used to generate
the next item. <em>next</em> returns the next item and modifies state.
<em>end</em> is the termination test; use <em>Infinite</em> for no
termination."
public LazyArray<state,val> lazyArray(state st, 
				    (state,val)(state) next, 
				    Bool(state) end = Infinite,
				    Void(state) cleanup = defaultCleanup,
				    Void(state) reset = defaultReset) 
{
    return LazyArray(st,st,next,end,cleanup,reset);
}

"Reset the state of a lazy Array to the initial state."
public Void reset(var LazyArray<state,val> list) 
{
    f = list.reset;
    f(list.current);
    list.current = list.init;
}

"Get the next element in a lazy list."
public val getNext(var LazyArray<state,val> gen) {
    if (end(gen)) {
	throw(EndOfArray);
    }
    p = gen.next(gen.current);
    gen.current = p.fst;
    return p.snd;
}

"Termination test for infinite lazy Arrays."
public Bool Infinite(a foo) = false;

"Check whether we have reached the end of a Array."
public Bool end(LazyArray<state,val> gen) {
    if (gen.end(gen.current)) {
	f = gen.cleanup;
	f(gen.current);
	return true;
    }
    return false;
}

"Turn a lazy Array into a real Array."
public [val] makeArray(LazyArray<state,val> gen) {
    list = [];
    reset(gen);
    while(!end(gen)) {
	push(list,getNext(gen));
    }
    return list;
}

"Generate a list of numbers lazily."
public LazyArray<Int,Int> lazyRange(Int start, Int end, Int step)
{
    return lazyArray(start-step,
		     lambda(x) { return (x+step, x+step); },
		     lambda(x) { if (step>0) { return (x+step)>end; }
		     else { return (x+step)<end; }
		     }
	);
}

"Map across an array lazily."
public LazyArray<Int,b> mapLazily(b(a) f, [a] xs) {
    return lazyArray(0,
		     lambda(x) { x++; return (x,f(xs[x-1])); },
		     lambda(x) -> { x==size(xs) });
}

"Map across a lazy array lazily."
public 
LazyArray<LazyArray<state,a>,b> lazyMap(b(a) f, LazyArray<state,a> xs) {
    reset(xs);
    return lazyArray(xs,
		     lambda(x) -> { f(getNext(x)) },
		     end);
}