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 indexBy(Function f, List l) {
245 THashMap map = new THashMap(l.size());
247 map.put(f.apply(o), o);
248 return new FunctionImpl1<Object,Object>() {
250 public Object apply(Object p0) {
256 // groupWith :: (a -> Integer) -> (a -> a -> Boolean) -> (a -> b) -> [a] -> [(b, [a])]
257 @SuppressWarnings("serial")
258 public static List<Tuple2> groupWith(final Function hash, final Function eq, Function keyFunction, Function valueFunction, List<Object> input) {
259 final TCustomHashMap<Object,ArrayList<Object>> map = new TCustomHashMap<Object,ArrayList<Object>>(
260 new HashingStrategy<Object>() {
262 public int computeHashCode(Object object) {
263 return (Integer)hash.apply(object);
267 public boolean equals(Object o1, Object o2) {
268 return (Boolean)eq.apply(o1, o2);
271 ArrayList<Tuple2> result = new ArrayList<Tuple2>();
272 for(Object o : input) {
273 Object key = keyFunction.apply(o);
274 ArrayList<Object> l = map.get(key);
276 l = new ArrayList<Object>();
278 result.add(new Tuple2(key, l));
280 l.add(valueFunction.apply(o));
285 public static List<Tuple2> group(List<Tuple2> input) {
286 THashMap<Object, ArrayList<Object>> groupMap = new THashMap<Object, ArrayList<Object>>();
287 ArrayList<Tuple2> result = new ArrayList<Tuple2>();
288 for(Tuple2 t : input) {
290 ArrayList<Object> list = groupMap.get(key);
292 list = new ArrayList<Object>();
293 groupMap.put(key, list);
294 result.add(new Tuple2(key, list));
301 public static List<Tuple2> groupBy(Function f, List<Tuple2> input) {
302 THashMap<Object, ArrayList<Object>> groupMap = new THashMap<Object, ArrayList<Object>>();
303 ArrayList<Tuple2> result = new ArrayList<Tuple2>();
304 for(Object value : input) {
305 Object key = f.apply(value);
306 ArrayList<Object> list = groupMap.get(key);
308 list = new ArrayList<Object>();
309 groupMap.put(key, list);
310 result.add(new Tuple2(key, list));
317 private static class GroupMapFunction extends FunctionImpl1<Object, List<Object>> {
318 THashMap<Object, ArrayList<Object>> groupMap;
319 public GroupMapFunction(THashMap<Object, ArrayList<Object>> groupMap) {
320 this.groupMap = groupMap;
323 public List<Object> apply(Object p0) {
324 List<Object> result = groupMap.get(p0);
326 return Collections.emptyList();
332 public static Function indexGroup(List<Tuple2> input) {
333 THashMap<Object, ArrayList<Object>> groupMap = new THashMap<Object, ArrayList<Object>>();
334 for(Tuple2 t : input) {
336 ArrayList<Object> list = groupMap.get(key);
338 list = new ArrayList<Object>();
339 groupMap.put(key, list);
343 return new GroupMapFunction(groupMap);
346 public static Function indexGroupBy(Function f, List<Tuple2> input) {
347 THashMap<Object, ArrayList<Object>> groupMap = new THashMap<Object, ArrayList<Object>>();
348 for(Object value : input) {
349 Object key = f.apply(value);
350 ArrayList<Object> list = groupMap.get(key);
352 list = new ArrayList<Object>();
353 groupMap.put(key, list);
357 return new GroupMapFunction(groupMap);
360 public static List sortWith(final Function compare, List l) {
361 Object[] result = l.toArray(new Object[l.size()]);
362 Arrays.sort(result, new Comparator() {
364 public int compare(Object o1, Object o2) {
365 return (Integer)compare.apply(o1, o2);
368 return Arrays.asList(result);
371 public static List uniqueWith(Function compare, List l) {
372 ArrayList result = new ArrayList(Math.min(10, l.size()));
374 for(int i=0;i<l.size();++i) {
375 Object el = l.get(i);
376 for(int j=0;j<result.size();++j)
377 if(compare.apply(el, result.get(j)).equals(Boolean.TRUE))
384 public static List deleteAllBy(Function compare, List a, List b) {
385 ArrayList result = new ArrayList(Math.min(10, a.size()));
389 if(compare.apply(el, el2).equals(Boolean.TRUE))
396 public static List listDifference(List a, List b) {
397 if(a.isEmpty() || b.isEmpty())
399 THashSet setB = new THashSet(b);
400 for(int i=0;i<a.size();++i) {
401 Object el = a.get(i);
402 if(setB.contains(el)) {
403 ArrayList result = new ArrayList(a.size()-1);
405 result.add(a.get(j));
406 for(++i;i<a.size();++i) {
408 if(!setB.contains(el))
417 public static List<Object> unique(List<Object> l) {
418 THashSet<Object> set = new THashSet<Object>(l.size());
419 ArrayList<Object> result = new ArrayList<Object>(l.size());
426 public static List<Object> uniqueBy(Function f, List<Object> l) {
427 THashSet<Object> set = new THashSet<Object>(l.size());
428 ArrayList<Object> result = new ArrayList<Object>(l.size());
430 if(set.add(f.apply(el)))