1 package org.simantics.scl.runtime;
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.Collections;
6 import java.util.Comparator;
7 import java.util.Iterator;
10 import org.simantics.scl.runtime.function.Function;
11 import org.simantics.scl.runtime.function.FunctionImpl1;
12 import org.simantics.scl.runtime.function.FunctionImpl2;
13 import org.simantics.scl.runtime.tuple.Tuple2;
15 import gnu.trove.map.hash.TCustomHashMap;
16 import gnu.trove.map.hash.THashMap;
17 import gnu.trove.set.hash.THashSet;
18 import gnu.trove.strategy.HashingStrategy;
21 @SuppressWarnings({"rawtypes", "unchecked"})
24 public static List map(Function f, List l) {
25 ArrayList result = new ArrayList(l.size());
27 result.add(f.apply(a));
31 public static void iter(Function f, List l) {
36 public static List filter(Function p, List l) {
37 ArrayList result = new ArrayList(Math.min(10, l.size()));
39 if((Boolean)p.apply(a))
44 public static List filterJust(List l) {
45 ArrayList result = new ArrayList(Math.min(10, l.size()));
52 public static List reverse(List l) {
53 ArrayList result = new ArrayList(l.size());
54 for(int i=l.size()-1;i>=0;--i)
59 public static Object foldl(Function f, Object initial, List l) {
61 initial = f.apply(initial, a);
65 // (b -> Maybe (a, b)) -> b -> [a]
66 public static List unfoldr(Function f, Object state) {
67 ArrayList result = new ArrayList();
69 Object r = f.apply(state);
78 public static Object foldr(Function f, Object initial, List l) {
79 for(int i=l.size()-1;i>=0;--i)
80 initial = f.apply(initial, l.get(i));
84 public static Object foldl1(Function f, List l) {
85 Iterator it = l.iterator();
86 Object initial = it.next();
88 initial = f.apply(initial, it.next());
92 public static Object foldr1(Function f, List l) {
94 Object initial = l.get(i);
96 initial = f.apply(initial, l.get(i));
100 public static List _pp(List a, List b) {
101 ArrayList result = new ArrayList(a.size() + b.size());
107 public static List concat(List l) {
110 size += ((List)e).size();
111 ArrayList result = new ArrayList(size);
113 result.addAll((List)e);
117 public static List append(List a, List b) {
118 ArrayList result = new ArrayList(a.size() + b.size());
124 public static List concatMap(Function f, List l) {
125 return concat(map(f, l));
128 public static int length(List l) {
132 public static boolean forall(Function p, List l) {
134 if(!(Boolean)p.apply(e))
139 public static boolean exists(Function p, List l) {
141 if((Boolean)p.apply(e))
146 public static Object get(List l, double i) {
147 return l.get((int)i);
150 private static final FunctionImpl2 BUILD_FUNC = new FunctionImpl2() {
152 public Object apply(Object p0, Object p1) {
153 ((ArrayList)p0).add(p1);
158 public static List build(Function f) {
159 return (List)f.apply(new ArrayList(), BUILD_FUNC);
162 public static List range(int from, int to) {
163 ArrayList result = new ArrayList();
171 public static List newList() {
172 return new ArrayList(2);
175 public static void add(List a, Object b) {
179 public static List zip(List a, List b) {
180 int len = Math.min(a.size(), b.size());
181 ArrayList result = new ArrayList(len);
182 for(int i=0;i<len;++i)
183 result.add(new Tuple2(a.get(i), b.get(i)));
187 public static List zipWith(Function f, List a, List b) {
188 int len = Math.min(a.size(), b.size());
189 ArrayList result = new ArrayList(len);
190 for(int i=0;i<len;++i)
191 result.add(f.apply(a.get(i), b.get(i)));
195 public static Tuple2 unzip(List in) {
197 ArrayList a = new ArrayList(len);
198 ArrayList b = new ArrayList(len);
199 for(int i=0;i<len;++i) {
200 Tuple2 tuple = (Tuple2)in.get(i);
204 return new Tuple2(a, b);
207 public static Function indexWith(final Function hash, final Function eq, List<Tuple2> l) {
208 final TCustomHashMap<Object,Object> map = new TCustomHashMap<Object,Object>(
209 new HashingStrategy<Object>() {
210 private static final long serialVersionUID = 3130052128660420673L;
213 public int computeHashCode(Object object) {
214 return (Integer)hash.apply(object);
218 public boolean equals(Object o1, Object o2) {
219 return (Boolean)eq.apply(o1, o2);
224 return new FunctionImpl1<Object,Object>() {
226 public Object apply(Object p0) {
232 public static Function index(List<Tuple2> l) {
233 THashMap map = new THashMap(l.size());
236 return new FunctionImpl1<Object,Object>() {
238 public Object apply(Object p0) {
244 public static Function indexSet(List<Object> l) {
245 THashSet set = new THashSet(l.size());
248 return new FunctionImpl1<Object,Object>() {
250 public Object apply(Object p0) {
251 return set.contains(p0);
256 public static Function indexBy(Function f, List l) {
257 THashMap map = new THashMap(l.size());
259 map.put(f.apply(o), o);
260 return new FunctionImpl1<Object,Object>() {
262 public Object apply(Object p0) {
268 // groupWith :: (a -> Integer) -> (a -> a -> Boolean) -> (a -> b) -> [a] -> [(b, [a])]
269 @SuppressWarnings("serial")
270 public static List<Tuple2> groupWith(final Function hash, final Function eq, Function keyFunction, Function valueFunction, List<Object> input) {
271 final TCustomHashMap<Object,ArrayList<Object>> map = new TCustomHashMap<Object,ArrayList<Object>>(
272 new HashingStrategy<Object>() {
274 public int computeHashCode(Object object) {
275 return (Integer)hash.apply(object);
279 public boolean equals(Object o1, Object o2) {
280 return (Boolean)eq.apply(o1, o2);
283 ArrayList<Tuple2> result = new ArrayList<Tuple2>();
284 for(Object o : input) {
285 Object key = keyFunction.apply(o);
286 ArrayList<Object> l = map.get(key);
288 l = new ArrayList<Object>();
290 result.add(new Tuple2(key, l));
292 l.add(valueFunction.apply(o));
297 public static List<Tuple2> group(List<Tuple2> input) {
298 THashMap<Object, ArrayList<Object>> groupMap = new THashMap<Object, ArrayList<Object>>();
299 ArrayList<Tuple2> result = new ArrayList<Tuple2>();
300 for(Tuple2 t : input) {
302 ArrayList<Object> list = groupMap.get(key);
304 list = new ArrayList<Object>();
305 groupMap.put(key, list);
306 result.add(new Tuple2(key, list));
313 public static List<Tuple2> groupBy(Function f, List<Tuple2> input) {
314 THashMap<Object, ArrayList<Object>> groupMap = new THashMap<Object, ArrayList<Object>>();
315 ArrayList<Tuple2> result = new ArrayList<Tuple2>();
316 for(Object value : input) {
317 Object key = f.apply(value);
318 ArrayList<Object> list = groupMap.get(key);
320 list = new ArrayList<Object>();
321 groupMap.put(key, list);
322 result.add(new Tuple2(key, list));
329 private static class GroupMapFunction extends FunctionImpl1<Object, List<Object>> {
330 THashMap<Object, ArrayList<Object>> groupMap;
331 public GroupMapFunction(THashMap<Object, ArrayList<Object>> groupMap) {
332 this.groupMap = groupMap;
335 public List<Object> apply(Object p0) {
336 List<Object> result = groupMap.get(p0);
338 return Collections.emptyList();
344 public static Function indexGroup(List<Tuple2> input) {
345 THashMap<Object, ArrayList<Object>> groupMap = new THashMap<Object, ArrayList<Object>>();
346 for(Tuple2 t : input) {
348 ArrayList<Object> list = groupMap.get(key);
350 list = new ArrayList<Object>();
351 groupMap.put(key, list);
355 return new GroupMapFunction(groupMap);
358 public static Function indexGroupBy(Function f, List<Tuple2> input) {
359 THashMap<Object, ArrayList<Object>> groupMap = new THashMap<Object, ArrayList<Object>>();
360 for(Object value : input) {
361 Object key = f.apply(value);
362 ArrayList<Object> list = groupMap.get(key);
364 list = new ArrayList<Object>();
365 groupMap.put(key, list);
369 return new GroupMapFunction(groupMap);
372 public static List sortWith(final Function compare, List l) {
373 Object[] result = l.toArray(new Object[l.size()]);
374 Arrays.sort(result, new Comparator() {
376 public int compare(Object o1, Object o2) {
377 return (Integer)compare.apply(o1, o2);
380 return Arrays.asList(result);
383 public static List uniqueWith(Function compare, List l) {
384 ArrayList result = new ArrayList(Math.min(10, l.size()));
386 for(int i=0;i<l.size();++i) {
387 Object el = l.get(i);
388 for(int j=0;j<result.size();++j)
389 if(compare.apply(el, result.get(j)).equals(Boolean.TRUE))
396 public static List deleteAllBy(Function compare, List a, List b) {
397 ArrayList result = new ArrayList(Math.min(10, a.size()));
401 if(compare.apply(el, el2).equals(Boolean.TRUE))
408 public static List listDifference(List a, List b) {
409 if(a.isEmpty() || b.isEmpty())
411 THashSet setB = new THashSet(b);
412 for(int i=0;i<a.size();++i) {
413 Object el = a.get(i);
414 if(setB.contains(el)) {
415 ArrayList result = new ArrayList(a.size()-1);
417 result.add(a.get(j));
418 for(++i;i<a.size();++i) {
420 if(!setB.contains(el))
429 public static List<Object> unique(List<Object> l) {
430 THashSet<Object> set = new THashSet<Object>(l.size());
431 ArrayList<Object> result = new ArrayList<Object>(l.size());
438 public static List<Object> uniqueBy(Function f, List<Object> l) {
439 THashSet<Object> set = new THashSet<Object>(l.size());
440 ArrayList<Object> result = new ArrayList<Object>(l.size());
442 if(set.add(f.apply(el)))