]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.runtime/scl/Prelude.scl
Adding getBytes for String in SCL
[simantics/platform.git] / bundles / org.simantics.scl.runtime / scl / Prelude.scl
1 import "JavaBuiltin" as Java
2 import "StringBuilder" as StringBuilder
3
4 /** The following types and names are builtin *************
5 data Boolean = True | False
6 data Byte
7 data Character
8 data Short
9 data Integer
10 data Long
11 data Float
12 data Double
13 data BooleanArray
14 data ByteArray
15 data CharacterArray
16 data ShortArray
17 data IntegerArray
18 data LongArray
19 data FloatArray
20 data DoubleArray
21 data Array a
22 data String
23 data a -> b
24 data [a] = [] | [a] | [a,a] | [a,a,a] | ...
25 data () = ()
26 data (a,b) = (a,b)
27 data (a,b,c) = (a,b,c)
28 data Maybe a = Nothing | Just a
29
30 fail :: String -> a
31
32 data TypeRep = TCon String | TApply TypeRep TypeRep
33 class Typeable a
34 typeOf :: Typeable a => a -> Type
35
36 data Binding a
37 class Serializable a
38 binding :: Serializable a => Binding a
39 ***********************************************************/
40
41 importJava "java.util.Arrays" where
42     @private
43     @JavaName toString
44     showDoubleArray :: DoubleArray -> String
45     
46     "Converts an array to a list."
47     @JavaName asList    
48     arrayToList :: Array a -> [a]
49
50 importJava "java.util.List" where
51     "Converts a list to an array."
52     @JavaName toArray
53     listToArray :: [a] -> Array a
54
55 instance Show DoubleArray where
56     show = showDoubleArray
57
58 importJava "org.simantics.scl.runtime.Coercion" where
59     "Converts a list of doubles to a double array."
60     toDoubleArray :: [Double] -> DoubleArray
61     "Converts a double array to a list of doubles."
62     fromDoubleArray :: DoubleArray -> [Double]
63
64 /*
65  * Precedences and associativity of all operators defined in Prelude
66  */
67
68 infixr 10 (!)
69 infixr 9  (.)
70 infixr 8  (^)
71 infixl 7  (*), (/), div, mod
72 infixl 6  (+), (-)
73 infixl 5  (\\), (<<), (<+)
74 infix  4  (!=), (<), (<=), (>=), (>)
75 infixr 3  (&&), (&<&)
76 infixr 2  (||), orElse, morelse
77 infixr 1  (>>=), (>>), (:=), (>=>)
78 infixr 1  ($)
79 infixl 1  catch
80
81 "Creates a constant function. `const x` defines a function that always returns `x`."
82 @inline
83 const :: a -> b -> a
84 const c x = c
85
86 """
87 Function application. `f $ x` is equivalent with `f x`. The function has two uses.
88 First is to remove parentheses from deeply nested expressions:
89
90     f (g (h x))  ==  f $ g $ h x
91     
92 The second use is with higher order functions:
93
94     map ($ parameter) functions
95 """
96 @macro
97 @inline
98 ($) :: (a -> <e> b) -> a -> <e> b
99 f $ x = f x
100
101 "Transforms a function taking a pair as a parameter to a function taking two values as a parameter."
102 @inline
103 curry :: ((a, b) -> <e> c) -> a -> b -> <e> c
104 curry f x y =  f (x, y)
105
106 "Transforms a function two values as a parameter to a function taking a pair as a parameter."
107 @inline
108 uncurry :: (a -> b -> <e> c) -> ((a, b) -> <e> c)
109 uncurry f (x, y) = f x y
110
111 "Transforms a function taking a triple as a parameter to a function taking three values as a parameter."
112 @inline
113 curry3 :: ((a, b, c) -> <e> d) -> a -> b -> c -> <e> d
114 curry3 f x y z =  f (x, y, z)
115
116 "Transforms a function three values as a parameter to a function taking a priple as a parameter."
117 @inline
118 uncurry3 :: (a -> b -> c -> <e> d) -> ((a, b, c) -> <e> d)
119 uncurry3 f (x, y, z) = f x y z
120
121 "Flips the parameters of a binary function."
122 @inline
123 flip :: (a -> b -> <e> c) -> b -> a -> <e> c
124 flip f x y =  f y x
125
126 "Swaps the order of elements of a pair (2-tuple)."
127 swap :: (a,b) -> (b,a)
128 swap (x,y) = (y,x)
129
130 /// Comparison ///
131
132 @inline
133 (!=) :: a -> a -> Boolean
134 a != b = not (a == b)
135
136 """
137 The class of linearly ordered types.
138 Method `compare` must be implemented in instances. 
139 """
140 class Ord a where
141     """
142     `compare x y` returns a negative number, if `x` is smaller than `y`,
143     a positive number, if `x` is bigger than `y` and zero if they are equal. 
144     """
145     compare :: a -> a -> Integer
146     compare a b = if a < b then -1 else if a > b then 1 else 0
147     
148     "Less"
149     (<) :: a -> a -> Boolean
150     a < b = compare a b < 0
151     "Less or equal"
152     (<=) :: a -> a -> Boolean
153     a <= b = compare a b <= 0
154     "Greater"
155     (>) :: a -> a -> Boolean
156     a > b = compare a b > 0
157     "Greater or equal"
158     (>=) :: a -> a -> Boolean
159     a >= b = compare a b >= 0
160     
161     "Minimum of the parameters"
162     min :: a -> a -> a
163     min a b = if a < b then a else b
164     "Maximum of the parameters"
165     max :: a -> a -> a
166     max a b = if a > b then a else b
167
168 """
169 Combines two integers such that if the first one is non-zero, it is returned, otherwise
170 the second-one. The second parameter is not implemented, if it is not needed.
171
172 The function is useful for implementing efficient recursive comparison of structures,
173 for example:
174
175     compare (x1,y1,z1) (x2,y2,z2) = compare x1 x2 &<& compare y1 y2 &<& compare z1 z2
176 """
177 @inline
178 (&<&) :: Integer -> (<e> Integer) -> <e> Integer
179 a &<& b = if a == 0 then b else a
180
181 "Maximum over a list"
182 @inline
183 maximum :: Ord a => [a] -> a
184 maximum = foldl1 max
185
186 "Minimum over a list"
187 @inline
188 minimum :: Ord a => [a] -> a
189 minimum = foldl1 min
190
191 "As `maximum` but compares the elements by the given projection."
192 maximumBy :: Ord b => (a -> <e> b) -> [a] -> <e> a
193 maximumBy f l = snd $ foldl1 maxF $ map (\x -> (f x, x)) l
194   where
195     maxF a b = if fst a >= fst b then a else b
196
197 """
198 As `minimum` but compares the elements by the given projection.
199 For example
200
201     minimumBy snd l
202     
203 returns a pair with the smallest second component.
204 """    
205 minimumBy :: Ord b => (a -> <e> b) -> [a] -> <e> a
206 minimumBy f l = snd $ foldl1 minF $ map (\x -> (f x, x)) l
207   where
208     minF a b = if fst a <= fst b then a else b  
209
210 /// Functions ///
211 /*
212 instance Functor ((->) a) where
213     map f g x = f (g x)
214
215 instance Monad ((->) a) where
216     return v x = v
217     (m >>= f) x = f (m x) x
218     join f x = f x x
219
220 instance Category (->) where
221     id x = x
222     @inline
223     (f . g) x = f (g x)
224 */
225 instance (Additive b) => Additive (a -> <e> b) where
226     zero x = zero
227     (f + g) x = f x + g x
228
229 instance (Ring b) => Ring (a -> <e> b) where
230     one x = one
231     (neg f) x = neg (f x)
232     (f - g) x = f x - g x
233     (f * g) x = f x * g x
234     (fromInteger c) x = fromInteger c
235
236 //instance Show (a -> <e> b) where
237 //    show f = "<function>"
238
239 "Appends a string to the string builder."
240 (<<) :: StringBuilder.T -> String -> <Proc> StringBuilder.T
241 (<<) =  StringBuilder.appendString
242
243 """
244 The class of types whose elements can be converted to a string representation.
245 Method `show` or `(<+)` must be implemented.
246 """
247 class Show a where
248     "Converts a value to string."
249     show :: a -> String
250     "Appends the string representation of the value to the string builder."
251     (<+) :: StringBuilder.T -> a -> <Proc> StringBuilder.T
252     """
253     Returns the precedence of the value. It is used to determine if parenteheses
254     are needed around the string representation of the value. The default value is 0
255     and means that parentheses are never added.
256     """ 
257     precedence :: a -> Integer
258     
259     "Converts a value to a string like `show` but does not put string literals in double quotes."
260     showForPrinting :: a -> String
261     
262     show v = runProc (StringBuilder.toString (StringBuilder.new <+ v))
263     showForPrinting v = show v
264     sb <+ v = StringBuilder.appendString sb (show v)
265     precedence v = 0
266
267 """
268 `Par` data type is used to control the placement of parentheses when converting values to string.
269 Value `Par prec val` is converted to string like `val` but parentheses are put around, if the 
270 precedence of the value is greater than `prec`.
271 """
272 data Par a = Par Integer a
273
274 instance (Show a) => Show (Par a) where
275     sb <+ (Par outerPrec v) = if prec > outerPrec
276                                  then sb << "(" <+ v << ")"
277                                  else sb <+ v
278                               where prec = precedence v
279
280 "Type class for parsing strings to values."
281 class Read a where
282     "Converts a string to a required type of value."
283     read :: String -> a
284 """
285 The `Additive` class is used for types that are additive monoids. The operations
286 must satisfy the following laws (at least approximately, when implemented for
287 floating point numbers):
288     (a + b) + c   = a + (b + c)
289     a + 0 = 0 + a = a
290 """
291 class Additive a where
292     """
293     Neutral element of (+), i.e,
294     
295         x + zero == x
296         zero + x == x       
297     """
298     zero :: a
299     "Adds two objects (numbers, vectors, strings, etc.) together."
300     (+)  :: a -> a -> a
301     """
302     Sum of the elements:
303     
304         sum [e1,e2,...,eN] = e1 + e2 + ... + eN
305     
306     Implemented usually more efficiently than with repetitive 
307     application of `(+)`.
308     """
309     sum  :: [a] -> a
310     sum = foldl (+) zero    
311 /*
312 class (Additive a) => AdditiveGroup a where
313     neg :: a -> a    
314     (-) :: a -> a -> a
315     x - y = x + (neg y)
316 */
317 """
318 The `Ring` class is used for types that are algebraic rings. The operations
319 must satisfy the following laws (at least approximately)
320 in addition to the laws of Additive:
321
322     a + b         = b + a
323     a - b         = a + (neg b)
324     a - a         = 0
325     (a * b) * c   = a * (b * c)
326     a * 1 = 1 * a = a
327     a * (b + c)   = a * b + a * c
328     (a + b) * c   = a * c + b * c 
329 """
330 class (Additive a) => Ring a where
331     """
332     Negation. Synonym for unary `-`.
333     """
334     neg :: a -> a
335     "Subtraction"    
336     (-) :: a -> a -> a
337     "Neutral element of multiplication"
338     one :: a
339     "Multiplication"
340     (*) :: a -> a -> a
341     "Converts an integer to a desired numeric type."
342     fromInteger :: Integer -> a
343     x - y = x + (neg y)
344     
345
346 """
347 The `OrderedRing` class combines the Ring and Ord classes. It additionally 
348 supports absolute value function.
349 """    
350 class (Ring a, Ord a) => OrderedRing a where
351     "Absolute value."
352     abs :: a -> a
353     abs x = if x < zero then neg x else x
354     "Converts the given number to `Integer`"
355     toInteger :: a -> Integer   
356
357 """
358 The `Integer` class is used for types that represent either all integers or some
359 range of them. 
360 """
361 class (OrderedRing a) => Integral a where
362     "Integer division truncated toward zero."
363     div :: a -> a -> a
364     "Integer remainder, satisfying ``(x `div` y)*y + (x `mod` y) = x``"    
365     mod :: a -> a -> a
366
367 """
368 The `Real` class is used for types that represent some approximation of real numbers. 
369 """
370 class (OrderedRing a) => Real a where
371     "Division"
372     (/) :: a -> a -> a
373     "Exponentation"
374     (^) :: a -> a -> a
375     "Pi (3.141592654...)"
376     pi  :: a
377     "Square root"
378     sqrt :: a -> a
379     "Exponent function"
380     exp :: a -> a
381     "Natural logarithm"
382     log :: a -> a 
383     "Sine"
384     sin :: a -> a
385     "Cosine"
386     cos :: a -> a
387     "Tangent"
388     tan :: a -> a
389     "Inverse sine"
390     asin :: a -> a
391     "Inverse cosine"
392     acos :: a -> a
393     "Inverse tangent."
394     atan :: a -> a
395     "Hyperbolic sine"
396     sinh :: a -> a
397     "Hyperbolic cosine"
398     cosh :: a -> a
399     "Hyperbolic tangent"
400     tanh :: a -> a
401     "Inverse hyberbolic sine"
402     asinh :: a -> a
403     "Inverse hyberbolic cosine"
404     acosh :: a -> a
405     "Inverse hyberbolic tangent"
406     atanh :: a -> a    
407     "The largest integer not greater than the given number"
408     floor :: a -> a
409     "The smallest integer not smaller than the given number"
410     ceil :: a -> a
411     round :: a -> Long
412     """
413     Two parameter version of `atan`. Its value is determined by the following
414     equations when (x,y) is a unit vector:
415     
416         x = cos (atan2 y x)
417         y = sin (atan2 y x)
418         
419     When x > 0,
420     
421         atan2 y x = atan (y/x)
422     """    
423     atan2 :: a -> a -> a
424     "Converts a `Double` value to a desired numeric type."
425     fromDouble :: Double -> a
426     "Converts the given number to `Double`"
427     toDouble :: a -> Double
428     
429     a ^ b = exp (b * log a)
430     
431     sinh x = 0.5 * (exp x - exp (neg x))
432     cosh x = 0.5 * (exp x + exp (neg x))
433     tanh x = (e2x - 1) / (e2x + 1) 
434       where
435         e2x = exp (2*x)
436        
437     asinh x = log (x + sqrt (x*x + one))
438     acosh x = log (x + sqrt (x*x - one))
439     atanh x = 0.5 * log ((one+x)/(one-x))
440     
441 /// Import mathematical functions ///
442
443 @private
444 importJava "java.lang.Math" where
445     @JavaName PI
446     piDouble :: Double
447     
448     @JavaName sin
449     sinDouble :: Double -> Double
450
451     @JavaName cos
452     cosDouble :: Double -> Double
453
454     @JavaName tan
455     tanDouble :: Double -> Double
456
457     @JavaName asin
458     asinDouble :: Double -> Double
459
460     @JavaName acos
461     acosDouble :: Double -> Double
462
463     @JavaName atan
464     atanDouble :: Double -> Double
465
466     @JavaName atan2    
467     atan2Double :: Double -> Double -> Double
468     
469     @JavaName sinh
470     sinhDouble :: Double -> Double
471
472     @JavaName cosh
473     coshDouble :: Double -> Double
474
475     @JavaName tanh
476     tanhDouble :: Double -> Double
477     
478     @JavaName exp
479     expDouble :: Double -> Double
480
481     @JavaName log
482     logDouble :: Double -> Double
483
484     @JavaName pow
485     powDouble :: Double -> Double -> Double
486
487     @JavaName sqrt
488     sqrtDouble :: Double -> Double
489     
490     @JavaName ceil
491     ceilDouble :: Double -> Double
492
493     @JavaName floor
494     floorDouble :: Double -> Double
495
496     @JavaName round
497     roundDouble :: Double -> Long
498     
499     @JavaName abs
500     absInteger :: Integer -> Integer
501
502     @JavaName abs
503     absLong :: Long -> Long
504
505     @JavaName abs
506     absFloat :: Float -> Float
507
508     @JavaName abs
509     absDouble :: Double -> Double
510         
511     @JavaName min
512     minInteger :: Integer -> Integer -> Integer
513
514     @JavaName min
515     minLong :: Long -> Long -> Long
516
517     @JavaName min
518     minFloat :: Float -> Float -> Float
519
520     @JavaName min
521     minDouble :: Double -> Double -> Double
522     
523     @JavaName max
524     maxInteger :: Integer -> Integer -> Integer
525
526     @JavaName max
527     maxLong :: Long -> Long -> Long
528
529     @JavaName max
530     maxFloat :: Float -> Float -> Float
531
532     @JavaName max
533     maxDouble :: Double -> Double -> Double
534
535 /// Integer ///
536
537 @private
538 importJava "java.lang.Byte" where
539     @JavaName toString
540     showByte :: Byte -> String
541     
542     @JavaName parseByte
543     readByte :: String -> Byte
544
545 instance Ord Byte where
546     (<) = Java.bcmplt
547     (<=) = Java.bcmple
548     (>) = Java.bcmpgt
549     (>=) = Java.bcmpge
550     
551 instance Additive Byte where
552     zero = Java.i2b Java.iconst_0
553     (+) = Java.badd
554     
555 instance Ring Byte where
556     neg = Java.bneg
557     (-) = Java.bsub
558     one = Java.i2b Java.iconst_1
559     (*) = Java.bmul
560     fromInteger = Java.i2b
561
562 instance Show Byte where
563     show = showByte
564     precedence v = if v >= 0 then 0 else 100
565
566 instance Read Byte where
567     read = readByte
568
569
570 @private
571 importJava "java.lang.Short" where
572     @JavaName toString
573     showShort :: Short -> String
574     
575     @JavaName parseShort
576     readShort :: String -> Short
577
578 instance Ord Short where
579     (<) = Java.scmplt
580     (<=) = Java.scmple
581     (>) = Java.scmpgt
582     (>=) = Java.scmpge
583     
584 instance Additive Short where
585     zero = Java.sconst_0
586     (+) = Java.sadd
587     
588 instance Ring Short where
589     neg = Java.sneg
590     (-) = Java.ssub
591     one = Java.sconst_1
592     (*) = Java.smul
593     fromInteger = Java.i2s
594
595 instance Show Short where
596     show = showShort
597     precedence v = if v >= 0 then 0 else 100
598
599 instance Read Short where
600     read = readShort
601     
602 /// Integer ///
603
604 @private
605 importJava "java.lang.Integer" where
606     @JavaName toString
607     showInteger :: Integer -> String
608     
609     @JavaName parseInt
610     readInteger :: String -> Integer
611
612 instance Ord Integer where
613     (<) = Java.icmplt
614     (<=) = Java.icmple
615     (>) = Java.icmpgt
616     (>=) = Java.icmpge
617
618 instance Additive Integer where
619     zero = Java.iconst_0
620     (+) = Java.iadd
621     
622 instance Ring Integer where
623     neg = Java.ineg
624     (-) = Java.isub
625     one = Java.iconst_1
626     (*) = Java.imul
627     fromInteger x = x
628     
629 instance OrderedRing Integer where
630     abs = absInteger
631     toInteger x = x
632
633 instance Integral Integer where
634     div = Java.idiv
635     mod = Java.irem
636
637 instance Show Integer where
638     show = showInteger
639     precedence v = if v >= 0 then 0 else 100
640
641 instance Read Integer where
642     read = readInteger
643
644 /// Long ///
645
646 @private
647 importJava "java.lang.Long" where
648     @JavaName toString
649     showLong :: Long -> String
650     
651     @JavaName parseLong
652     readLong :: String -> Long
653
654 instance Ord Long where
655     (<) = Java.lcmplt
656     (<=) = Java.lcmple
657     (>) = Java.lcmpgt
658     (>=) = Java.lcmpge
659
660 instance Additive Long where
661     zero = Java.lconst_0
662     (+) = Java.ladd
663     
664 instance Ring Long where
665     neg = Java.lneg
666     (-) = Java.lsub
667     one = Java.lconst_1
668     (*) = Java.lmul
669     fromInteger = Java.i2l
670     
671 instance OrderedRing Long where
672     abs = absLong
673     toInteger = Java.l2i
674
675 instance Integral Long where
676     div = Java.ldiv
677     mod = Java.lrem
678     
679 instance Show Long where
680     show = showLong
681     precedence v = if v >= 0 then 0 else 100
682
683 instance Read Long where
684     read = readLong
685     
686 /// Float ///
687
688 importJava "java.lang.Float" where
689     @private
690     @JavaName compare
691     compareFloat :: Float -> Float -> Integer
692
693     @private
694     @JavaName toString
695     showFloat :: Float -> String
696
697     @private
698     @JavaName parseFloat
699     readFloat :: String -> Float
700     
701     "Converts 32-bit floating point number to a 32-bit integer with the same byte level representation."
702     floatToIntBits :: Float -> Integer  
703
704 instance Ord Float where
705     compare = compareFloat
706     (<) = Java.fcmplt
707     (<=) = Java.fcmple
708     (>) = Java.fcmpgt
709     (>=) = Java.fcmpge
710
711 instance Additive Float where
712     zero = Java.fconst_0
713     (+) = Java.fadd
714     
715 instance Ring Float where
716     neg = Java.fneg
717     (-) = Java.fsub
718     one = Java.fconst_1
719     (*) = Java.fmul
720     fromInteger = Java.i2f
721
722 instance OrderedRing Float where
723     abs = absFloat
724     toInteger = Java.f2i
725     
726 instance Real Float where
727     (/) = Java.fdiv
728     x ^ y = Java.d2f (powDouble (Java.f2d x) (Java.f2d y))
729     pi = fromDouble piDouble
730     sqrt = Java.d2f . sqrtDouble . Java.f2d
731     exp = Java.d2f . expDouble . Java.f2d
732     log = Java.d2f . logDouble . Java.f2d
733     sin = Java.d2f . sinDouble . Java.f2d
734     cos = Java.d2f . cosDouble . Java.f2d
735     tan = Java.d2f . tanDouble . Java.f2d
736     asin = Java.d2f . asinDouble . Java.f2d
737     acos = Java.d2f . acosDouble . Java.f2d
738     atan = Java.d2f . atanDouble . Java.f2d
739     sinh = Java.d2f . sinhDouble . Java.f2d
740     cosh = Java.d2f . coshDouble . Java.f2d
741     tanh = Java.d2f . tanhDouble . Java.f2d
742     floor = Java.d2f . floorDouble . Java.f2d
743     ceil = Java.d2f . ceilDouble . Java.f2d
744     atan2 y x = Java.d2f (atan2Double (Java.f2d y) (Java.f2d x))
745     round = roundDouble . Java.f2d
746     fromDouble = Java.d2f
747     toDouble = Java.f2d
748
749 instance Show Float where
750     show = showFloat
751     precedence v = if v >= 0 then 0 else 100
752
753 instance Read Float where
754     read = readFloat
755     
756 /// Double ///
757
758 importJava "java.lang.Double" where
759     @private
760     @JavaName compare
761     compareDouble :: Double -> Double -> Integer
762     
763     @private
764     @JavaName toString
765     showDouble :: Double -> String
766     
767     @private
768     @JavaName parseDouble
769     readDouble :: String -> Double
770     
771     "Converts 64-bit floating point number to a 64-bit integer with the same byte level representation."
772     doubleToLongBits :: Double -> Long
773     
774     isFinite :: Double -> Boolean
775     isNaN :: Double -> Boolean
776     isInfinite :: Double -> Boolean
777
778 instance Ord Double where
779     compare = compareDouble
780     (<) = Java.dcmplt
781     (<=) = Java.dcmple
782     (>) = Java.dcmpgt
783     (>=) = Java.dcmpge 
784
785 instance Additive Double where
786     zero = Java.dconst_0
787     (+) = Java.dadd
788     
789 instance Ring Double where
790     neg = Java.dneg
791     (-) = Java.dsub
792     one = Java.dconst_1
793     (*) = Java.dmul
794     fromInteger = Java.i2d
795
796 instance OrderedRing Double where
797     abs = absDouble
798     toInteger = Java.d2i
799     
800 instance Real Double where
801     (/) = Java.ddiv
802     (^) = powDouble
803     pi = piDouble
804     sqrt = sqrtDouble
805     exp = expDouble
806     log = logDouble
807     sin = sinDouble
808     cos = cosDouble
809     tan = tanDouble
810     asin = asinDouble
811     acos = acosDouble
812     atan = atanDouble
813     sinh = sinhDouble
814     cosh = coshDouble
815     tanh = tanhDouble
816     floor = floorDouble
817     ceil = ceilDouble
818     atan2 = atan2Double
819     round = roundDouble
820     fromDouble x = x
821     toDouble x = x
822
823 instance Show Double where
824     show = showDouble
825     precedence v = if v >= 0 then 0 else 100
826
827 instance Read Double where
828     read = readDouble
829
830 /// Character ///
831
832 importJava "java.lang.Character" where
833     @JavaName toString
834     showCharacter :: Character -> String
835     
836     "Returns true, if the given character is a letter."
837     isLetter :: Character -> Boolean
838     
839     "Returns true, if the given character is a digit."
840     isDigit :: Character -> Boolean
841
842 instance Ord Character where
843     (<) = Java.ccmplt
844     (<=) = Java.ccmple
845     (>) = Java.ccmpgt
846     (>=) = Java.ccmpge
847     
848 instance Show Character where
849     sb <+ c = sb << "'" << showCharacter c << "'"
850     
851 "Adds a given integer to the character code."
852 addChar :: Character -> Integer -> Character
853 addChar = Java.cadd
854
855 "Subtracts a given integer from the character code."
856 subChar :: Character -> Character -> Integer
857 subChar = Java.csub
858
859 /// Functor ///
860
861 """
862 The `Functor` class is used for types that can be mapped over. Instances of `Functor` should satisfy the following laws:
863
864     fmap id  ==  id
865     fmap (f . g)  ==  fmap f . fmap g
866 """
867 class Functor f where
868     "Lifts a pure function to the given functor."
869     fmap :: (a -> b) -> f a -> f b
870 /*
871 class CoFunctor f where
872     comap :: (a -> b) -> f b -> f a
873 */
874 /// Applicative ///
875 /*
876 class (Functor f) => Applicative f where
877     return :: a -> f a
878     (<*>) :: f (a -> b) -> f a -> f b
879     (*>) :: f a -> f b -> f b
880     (<*) :: f a -> f b -> f a
881     
882     u *> v = pure (const id) <*> u <*> v
883     u <* v = pure const <*> u <*> v
884     fmap f x = pure f <*> x
885 */
886 /// Monad ///
887
888 """
889 The `Monad` class defines the basic operations over a monad, a concept from a branch of mathematics known as category theory.
890 From the perspective of a SCL programmer, however, it is best to think of a monad as an abstract datatype of actions.
891 SCL's `mdo expressions provide a convenient syntax for writing monadic expressions.
892
893 Instances of `Monad` should satisfy the following laws:
894
895     return a >>= k  ==  k a
896     m >>= return  ==  m
897     m >>= (\x -> k x >>= h)  ==  (m >>= k) >>= h
898     fmap f xs  ==  xs >>= return . f
899 """
900 class (Functor m) => Monad m where
901     "Inject a value into the monadic type."
902     return :: a -> m a
903     "Sequentially compose two actions, passing any value produced by the first as an argument to the second."
904     (>>=) :: m a -> (a -> m b) -> m b
905     """
906     The join function is the conventional monad join operator. It removes one level of monadic
907     structure.
908     
909     For lists, `join` concatenates a list of lists:
910     
911         join [[1,2], [3,4]] = [1, 2, 3, 4]
912     """
913     join :: m (m a) -> m a
914     join m = m >>= id
915
916 """
917 Sequentially compose two actions, discarding any value produced by the first, like sequencing operators
918 (such as the semicolon) in imperative languages."
919 """
920 @macro
921 (>>) :: Monad m => m a -> m b -> m b
922 a >> b = a >>= (\_ -> b)
923
924 "Left-to-right Kleisli composition of monads."
925 (>=>) :: Monad m => (a -> m b) -> (b -> m c) -> (a -> m c)
926 (f >=> g) x = (f x) >>= g 
927
928 "While loop. `while cond body` executes the `body` while the `cond` is true." 
929 @inline
930 while :: (<e> Boolean) -> (<e> a) -> <e> ()
931 while cond body = loop ()
932   where loop _ = if cond 
933                  then do body ; loop ()
934                  else ()
935
936 """
937 Sequences the given monadic value infinitely:
938
939     repeatForever m = m >> m >> m >> ...
940 """
941 repeatForever m = m >> repeatForever m
942
943 replicateM :: Monad m => Integer -> m a -> m [a]
944 replicateM count m = loop count emptyList
945   where
946     loop count l | count <= 0 = return l
947                  | otherwise  = mdo
948                      v <- m
949                      loop (count-1) (addList l v)
950
951 replicateM_ :: Monad m => Integer -> m a -> m ()
952 replicateM_ count m | count <= 0 = return ()
953                     | otherwise  = m >> replicateM_ (count-1) m
954
955 /// MonadZero ///
956
957 """
958 A class of monads with zero element satisfying
959
960     mzero >>= f = mzero
961 """ 
962 class (Monad m) => MonadZero m where
963     mzero :: m a
964
965 "Injects a boolean test to a type beloning to `MonadZero`."
966 guard :: MonadZero m => Boolean -> m ()
967 guard True = return ()
968 guard False = mzero
969
970 /// MonadPlus ///
971
972 """
973 A class of monads with associative binary operator `mplus` satisfying the following laws:  
974
975     mplus mzero b = b
976     mplus a mzero = a
977     mplus (mplus a b) c = mplus a (mplus b c)
978     mplus a b >>= k = mplus (a >>= k) (b >>= k)
979 """
980 class (MonadZero m) => MonadPlus m where
981     mplus :: m a -> m a -> m a
982
983 /// MonadOr ///
984
985 """
986 A class of monads with associative binary operator `morelse` satisfying the following laws:  
987
988     morelse mzero b = b
989     morelse a mzero = a
990     morelse (morelse a b) c = morelse a (morelse b c)
991     morelse (return a) b = return a
992 """
993 class (MonadZero m) => MonadOr m where
994     morelse :: m a -> m a -> m a
995
996 /// FunctorE ///
997
998 """
999 A class of types that can be mapped over with effectful mapping functions.
1000 """
1001 class (Functor f) => FunctorE f where
1002     """
1003     Applies the function to all elements of the container and
1004     returns the similarly shaped container with the results:
1005     
1006     For lists,
1007     
1008         map f [e1, e2, ..., eN] = [f e1, f e2, ..., f eN]
1009         
1010     for example
1011     
1012         map (*2) [1..5] = [2, 4, 6, 8, 10]
1013     """
1014     map :: (a -> <e> b) -> f a -> <e> (f b)
1015     "Calls the given function with all elements of the given container."
1016     iter :: (a -> <e> b) -> f a -> <e> ()
1017     "Calls the given function with all elements of the given container giving also the index of the element as a parameter."
1018     iterI :: (Integer -> a -> <e> b) -> f a -> <e> ()
1019
1020 "Iterates the elements of the given collection. Same as `iter` but parameters flipped." 
1021 for :: FunctorE f => f a -> (a -> <e> b) -> <e> ()
1022 @macro
1023 for l f = iter f l
1024
1025 "Iterates the elements of the given collection providing also the indices of the elements. Same as `iterI` but parameters flipped." 
1026 forI :: FunctorE f => f a -> (Integer -> a -> <e> b) -> <e> ()
1027 @macro
1028 forI l f = iterI f l
1029
1030 "`forN n f` calls `f` for all integers `0`, ..., `n-1`"
1031 @inline
1032 forN :: Integer -> (Integer -> <e> b) -> <e> ()
1033 forN n f = loop 0
1034   where
1035     loop i = if i < n
1036              then do f i ; loop (i+1)
1037              else ()
1038
1039 @inline
1040 mapI :: (Integer -> a -> <e> b) -> [a] -> <e> [b]
1041 mapI f l = build (\empty cons -> let
1042     len = length l
1043     loop i accum = if i < len
1044                    then loop (i+1) (cons accum (f i (l!i)))
1045                    else accum
1046   in loop 0 empty)
1047
1048 """
1049 `mapMaybe` combines `map` and `filter` functions. 
1050 It applies the given function to every element of the input list. If the result
1051 is `Just x`, then `x` is added to the resulting list.
1052
1053     mapMaybe f lst = [y | x <- lst, Just y = f x]
1054 """
1055 @inline
1056 mapMaybe :: (a -> <e> Maybe b) -> [a] -> <e> [b]
1057 mapMaybe f l = build (\empty cons -> foldl (\cur x -> match f x with Just v -> cons cur v ; _ -> cur) empty l)
1058
1059 """
1060 Applies the given function to all elements of the list. Produces two lists: the first contains all elements `x`
1061 for which the function returned `Left x` and the second list contains all elements `y` for which the function
1062 returned `Right y`.
1063 """
1064 mapEither :: (a -> <e> Either b c) -> [a] -> <e> ([b], [c])
1065 mapEither f list = runProc do
1066     l = newArrayList
1067     r = newArrayList
1068     for list (\x -> match f x with
1069         Left v -> addArrayList l v
1070         Right v -> addArrayList r v)
1071     (Java.unsafeCoerce l, Java.unsafeCoerce r)
1072
1073 "`replicate n v` returns a list of length `n` such that each element is a copy of `v`."
1074 @inline
1075 replicate :: Integer -> a -> [a]
1076 replicate n v = build (\empty cons ->
1077     let aux 0 l = l
1078         aux i l = aux (i-1) (cons l v)
1079     in aux n empty 
1080     )
1081
1082 /// FunctorM ///
1083
1084 class (FunctorE f) => FunctorM f where
1085     "`mapM f` is equivalent to `sequence . map f`."
1086     mapM :: Monad m => (a -> <e> m b) -> f a -> <e> m (f b)
1087     "Evaluate each action in the sequence from left to right, and collect the results."
1088     sequence :: Monad m => f (m a) -> m (f a) 
1089     mapM f l = sequence (map f l)
1090
1091 /// MonadE ///
1092
1093 class (FunctorE m, Monad m) => MonadE m where
1094     bindE :: m a -> (a -> <e> m b) -> <e> m b
1095
1096 instance MonadE Maybe where
1097     bindE Nothing  _ = Nothing
1098     bindE (Just v) f = f v
1099     
1100 instance MonadE (Either a) where
1101     bindE (Left v)  _ = Left v
1102     bindE (Right v) f = f v
1103
1104 instance MonadE [] where
1105     bindE l f = concatMap f l
1106     
1107 /// Category ///
1108
1109 "Identity function."
1110 id :: a -> a
1111 id x = x
1112
1113 """
1114 Ignores the given value. This function is used in a situation where a function returns
1115 a value in a context where the value is not expected.
1116 """
1117 @inline
1118 ignore :: a -> ()
1119 ignore _ = ()
1120
1121 @inline
1122 ignoreM :: a -> Maybe b
1123 ignoreM _ = Nothing
1124
1125 """
1126 Composes two functions
1127     (f . g) x = f (g x)
1128 """
1129 (.) :: (b -> <e> c) -> (a -> <e> b) -> (a -> <e> c)
1130 (f . g) x = f (g x)
1131
1132 /// Sequence ///
1133
1134 "A type class for sequences. All sequences must support indexing by integers."
1135 class /*(Additive a) =>*/ Sequence a where
1136     "Length of the sequence"
1137     length :: a -> Integer
1138     "`take n s` returns the first `n` elements of the sequence `s`."
1139     take :: Integer -> a -> a
1140     "`drop n s` removes the first `n` elements of the sequence `s`."
1141     drop :: Integer -> a -> a
1142     """
1143     `sub s begin end` returns a subsequence of `s` starting from
1144     index `begin` and ending just before index `end`.
1145     """ 
1146     sub :: a -> Integer -> Integer -> a
1147     
1148     take n v = sub v 0 (min n (length v))
1149     drop n v = sub v (min n len) len
1150       where
1151         len = length v 
1152
1153 instance Sequence [a] where
1154     length = lengthList
1155     sub = subList
1156     
1157 instance Sequence String where
1158     length = lengthString
1159     sub = subString        
1160
1161 class IndexedSequence f where
1162     "`seq ! i` returns the `i`th element of the sequence `seq`. Indexing starts from zero."
1163     (!) :: f a -> Integer -> a
1164
1165 "Returns the first element of a sequence"
1166 @inline
1167 first l = l!0
1168
1169 "Returns the last element of a sequence"
1170 @inline
1171 last l = l!(length l-1)
1172
1173 instance IndexedSequence [] where
1174     (!) = getList
1175
1176 /// Boolean ///
1177
1178 """
1179 Equivalent to the boolean value `True`. The value is meant to be used in
1180 guard patterns:
1181
1182     min a b | a < b     = a
1183             | otherwise = b 
1184 """
1185 @inline
1186 otherwise :: Boolean
1187 otherwise = True
1188
1189 instance Ord Boolean where
1190     compare False False = 0
1191     compare False True  = neg 1
1192     compare True  False = 1
1193     compare True  True  = 0
1194
1195 instance Show Boolean where
1196     show True = "True"
1197     show False = "False"
1198
1199 """
1200 Boolean conjunction (and). The function is a macro that evaluates the second parameter
1201 only if the first parameter is `True`.
1202
1203 <table>
1204 <tr><th>a</th><th>b</th><th>a && b</th></tr>
1205 <tr><td>True</td><td>True</td><td>True</td></tr>
1206 <tr><td>True</td><td>False</td><td>False</td></tr>
1207 <tr><td>False</td><td>not evaluated</td><td>False</td></tr>
1208 </table> 
1209 """
1210 @macro
1211 (&&) :: Boolean -> Boolean ->  Boolean
1212 a && b = if a then b else False
1213
1214 """
1215 Boolean disjunction (or). The function is a macro that evaluates the second parameter
1216 only if the first parameter is `False`.
1217
1218 <table>
1219 <tr><th>a</th><th>b</th><th>a || b</th></tr>
1220 <tr><td>True</td><td>not evaluated</td><td>True</td></tr>
1221 <tr><td>False</td><td>True</td><td>True</td></tr>
1222 <tr><td>False</td><td>False</td><td>False</td></tr>
1223 </table> 
1224 """
1225 @macro
1226 (||) :: Boolean -> Boolean -> Boolean
1227 a || b = if a then True else b
1228
1229 "Boolean negation"
1230 @inline
1231 not a = if a then False else True
1232
1233 /// Maybe ///
1234
1235 //data Maybe a = Nothing | Just a
1236
1237 "Given `Just x` this function returns `x`. If the parameter is `Nothing`, the function raises an exception."
1238 fromJust :: Maybe a -> a
1239 fromJust (Just a) = a
1240
1241 deriving instance (Ord a) => Ord (Maybe a)
1242 deriving instance (Show a) => Show (Maybe a)
1243
1244 instance Functor Maybe where
1245     fmap _ Nothing  = Nothing
1246     fmap f (Just x) = Just (f x)
1247
1248 instance FunctorE Maybe where
1249     map _ Nothing  = Nothing
1250     map f (Just x) = Just (f x)
1251     
1252     iter _ Nothing = ()
1253     iter f (Just x) = ignore (f x)
1254     
1255     iterI _ Nothing = ()
1256     iterI f (Just x) = ignore (f 0 x)
1257     
1258 instance Monad Maybe where    
1259     return x = Just x
1260
1261     @inline
1262     Nothing >>= _ = Nothing
1263     Just x  >>= f = f x
1264
1265     @inline
1266     join Nothing  = Nothing
1267     join (Just x) = x
1268
1269 instance MonadZero Maybe where
1270     mzero = Nothing
1271
1272 instance MonadOr Maybe where
1273     morelse a@(Just _) _ = a
1274     morelse _ b = b
1275
1276 "`execJust v f` executes the function `f` with parameter value `x`, if `v=Just x`. If `v=Nothing`, the function does nothing."
1277 @inline
1278 execJust :: Maybe a -> (a -> <e> b) -> <e> ()
1279 execJust maybeValue procedure = match maybeValue with
1280     Just v -> ignore $ procedure v
1281     _ -> ()
1282
1283 "`fromMaybe def v` returns `def` if `v=Nothing` and `x` if `v=Just x`."
1284 @inline
1285 fromMaybe :: a -> Maybe a -> a
1286 fromMaybe default maybeValue = match maybeValue with
1287     Just v -> v
1288     _ -> default
1289     
1290     
1291 """
1292 Provides a default value if the first parameter is Nothing.
1293 The default value is evaluated only if needed. The function
1294 can be used as an operator and is right associative so that
1295 the following is possible:
1296
1297     tryWithTheFirstMethod
1298         `orElse` tryWithTheSecondMethod
1299         `orElse` fail "Didn't succeed."
1300 """
1301 @inline
1302 orElse :: Maybe a -> (<e> a) -> <e> a
1303 orElse (Just x) _   = x
1304 orElse Nothing  def = def
1305
1306 /// Either ///
1307
1308 """
1309 The Either type represents values with two possibilities: a value of type `Either a b` is either `Left a` or `Right b`.
1310
1311 The `Either` type is sometimes used to represent a value which is either correct or an error; by convention, the `Left` constructor
1312 is used to hold an error value and the `Right` constructor is used to hold a correct value (mnemonic: "right" also means "correct").
1313 """
1314 @JavaType "org.simantics.scl.runtime.either.Either"
1315 data Either a b =
1316     @JavaType "org.simantics.scl.runtime.either.Left"
1317     @FieldNames [value]
1318     Left a
1319   | @JavaType "org.simantics.scl.runtime.either.Right"
1320     @FieldNames [value]
1321     Right b
1322
1323 deriving instance (Ord a, Ord b) => Ord (Either a b)
1324 deriving instance (Show a, Show b) => Show (Either a b)
1325
1326 instance Functor (Either a) where
1327     fmap _ (Left x)  = Left x
1328     fmap f (Right y) = Right (f y)
1329
1330 instance FunctorE (Either a) where
1331     map _ (Left x)  = Left x
1332     map f (Right y) = Right (f y)
1333     
1334     iter _ (Left x) = ()
1335     iter f (Right y) = ignore (f y)
1336     
1337     iterI _ (Left x) = ()
1338     iterI f (Right y) = ignore (f 0 y)
1339         
1340 instance Monad (Either b) where
1341     return y = Right y
1342
1343     Left x  >>= _ = Left x
1344     Right y >>= f = f y
1345
1346     join (Left x)  = Left x
1347     join (Right y) = y
1348     
1349 /// String ///
1350
1351 importJava "java.lang.String" where
1352     @private
1353     @JavaName "concat"
1354     concatString :: String -> String -> String
1355     @private
1356     @JavaName "compareTo"
1357     compareString :: String -> String -> Integer
1358     @private
1359     @JavaName "length"
1360     lengthString :: String -> Integer
1361
1362     """
1363     `replaceString original pattern replacement` replaces all occurrences of `pattern` in the string by `replacement`.
1364     """ 
1365     @JavaName replace
1366     replaceString :: String -> String -> String -> String
1367     
1368     @private
1369     @JavaName split
1370     splitString_ :: String -> String -> Array String
1371     
1372     """
1373     `indexOf string s` finds the first occurrence of `s` from `string` and returns its index.
1374     If the `s` does not occur in the string, return `-1`."
1375     """
1376     @JavaName indexOf
1377     indexOf :: String -> String -> Integer
1378     
1379     "Works like `indexOf` but starts searching from the given index instead of the beginning of the string."
1380     @JavaName indexOf
1381     indexOfStartingFrom :: String -> String -> Integer -> Integer
1382     
1383     "Works like `indexOf` but returns the index of the last occurrence."
1384     @JavaName lastIndexOf
1385     lastIndexOf :: String -> String -> Integer
1386     
1387     "Works like `lastIndexOf` but starts searching from the given index instead of the end of the string."
1388     @JavaName lastIndexOf
1389     lastIndexOfStartingFrom :: String -> String -> Integer -> Integer
1390     
1391     @private
1392     @JavaName substring
1393     subString :: String -> Integer -> Integer -> String
1394
1395     """
1396     `regionMatches str1 offset1 str2 offset2 len` tests whether
1397     `sub str1 offset1 (offset1+len) == sub str2 offset2 (offset2+len)`.
1398     """
1399     regionMatches :: String -> Integer -> String -> Integer -> Integer -> Boolean
1400
1401     "`startsWith string prefix` returns true if the string begins with the given prefix."
1402     startsWith :: String -> String -> Boolean
1403     
1404     "`endsWith string suffix` returns true if the string ends with the given prefix."
1405     endsWith :: String -> String -> Boolean
1406     
1407     "Removes leading and trailing whitespace from the string."
1408     trim :: String -> String
1409     
1410     "`contains string s` returns true if `string` contains `s` as a substring."
1411     contains :: String -> String -> Boolean
1412     
1413     "`charAt string i` returns the `i`th character of the string."
1414     charAt :: String -> Integer -> Character
1415     
1416     "Converts all letters of the string to lower case."
1417     toLowerCase :: String -> String
1418     "Converts all letters of the string to upper case."
1419     toUpperCase :: String -> String
1420     
1421     "Creates a string from a vector of characters."
1422     @JavaName "<init>"
1423     string :: Vector Character -> String
1424     
1425     getBytes :: String -> String -> ByteArray
1426
1427 getBytesUTF8 :: String -> ByteArray
1428 getBytesUTF8 str = getBytes str "UTF-8"
1429
1430 instance Ord String where
1431     compare = compareString
1432     
1433 instance Additive String where
1434     zero = ""
1435     (+) = concatString
1436     sum ss = runProc (StringBuilder.toString $ foldl StringBuilder.appendString StringBuilder.new ss)
1437
1438 @private
1439 importJava "org.simantics.scl.runtime.string.StringEscape" where
1440     appendEscapedString :: StringBuilder.T -> String -> <Proc> StringBuilder.T
1441
1442 instance Show String where
1443     showForPrinting = id
1444     sb <+ v = (appendEscapedString (sb << "\"") v) << "\""
1445
1446 instance Read String where
1447     read str = str
1448     
1449 @deprecated "Instead of 'splitString text pattern', write 'split pattern text' (note change in the parameter order)." 
1450 "`splitString text pattern` splits the string into a list of string where the parts are sepratated in the original list by the given pattern."
1451 splitString :: String -> String -> [String]
1452 splitString source pattern = arrayToList $ splitString_ source pattern
1453
1454 """
1455 `split pattern text` splits `text` around matches of the given regular expression `pattern`.
1456
1457 This function works as if by invoking the two-argument split method with the given expression and a limit argument of zero. Trailing empty strings are therefore not included in the resulting array.
1458
1459 The string "boo:and:foo", for example, yields the following results with these expressions:
1460
1461     Regex   Result
1462     :       { "boo", "and", "foo" }
1463     o       { "b", "", ":and:f" }
1464 """
1465 split :: String -> String -> [String]
1466 split pattern text = arrayToList $ splitString_ text pattern
1467
1468 /// Tuple0 ///
1469
1470 instance Ord () where
1471     compare () () = 0
1472
1473 instance Additive () where
1474     zero = ()
1475     () + () = ()
1476
1477 instance Show () where
1478     show () = "()"
1479
1480 /// Tuple2 ///
1481
1482 "Gives the first element of a pair."
1483 @inline
1484 fst :: (a,b) -> a
1485 fst (x,y) = x
1486
1487 "Gives the second element of a pair."
1488 @inline
1489 snd :: (a,b) -> b
1490 snd (x,y) = y
1491
1492 @inline
1493 mapFst :: (a -> b) -> (a,c) -> (b,c)
1494 mapFst f (x,y) = (f x, y)
1495
1496 @inline
1497 mapSnd :: (a -> b) -> (c,a) -> (c,b)
1498 mapSnd f (x,y) = (x, f y)
1499
1500 instance (Ord a, Ord b) => Ord (a, b) where
1501     compare (a0, b0) (a1, b1) = compare a0 a1 &<& compare b0 b1
1502
1503 instance (Additive a, Additive b) => Additive (a, b) where
1504     zero = (zero, zero)
1505     (a0, b0) + (a1, b1) = (a0+a1, b0+b1)
1506
1507 instance Functor ((,) a) where
1508     fmap f (a,b) = (a, f b)
1509     
1510 instance (Show a, Show b) => Show (a, b) where
1511     sb <+ (x, y) = sb << "(" <+ x << ", " <+ y << ")"
1512
1513 /// Tuple3 ///
1514
1515 instance (Ord a, Ord b, Ord c) => Ord (a, b, c) where
1516     compare (a0, b0, c0) (a1, b1, c1) = compare a0 a1 &<& compare b0 b1 &<& compare c0 c1
1517
1518 instance (Additive a, Additive b, Additive c) => Additive (a, b, c) where
1519     zero = (zero, zero, zero)
1520     (a0, b0, c0) + (a1, b1, c1) = (a0+a1, b0+b1, c0+c1)
1521
1522 instance Functor ((,,) a b) where
1523     fmap f (a,b,c) = (a, b, f c)
1524
1525 instance (Show a, Show b, Show c) => Show (a, b, c) where
1526     sb <+ (x, y, z) = sb << "(" <+ x << ", " <+ y << ", " <+ z << ")"
1527
1528 /// Tuple4 ///
1529
1530 instance (Ord a, Ord b, Ord c, Ord d) => Ord (a, b, c, d) where
1531     compare (a0, b0, c0, d0) (a1, b1, c1, d1) = 
1532         compare a0 a1 &<& compare b0 b1 &<& compare c0 c1 &<& compare d0 d1
1533
1534 instance (Additive a, Additive b, Additive c, Additive d) => Additive (a, b, c, d) where
1535     zero = (zero, zero, zero, zero)
1536     (a0, b0, c0, d0) + (a1, b1, c1, d1) = (a0+a1, b0+b1, c0+c1, d0+d1)
1537
1538 instance Functor ((,,,) a b c) where
1539     fmap f (a,b,c,d) = (a, b, c, f d)
1540
1541 instance (Show a, Show b, Show c, Show d) => Show (a, b, c, d) where
1542     sb <+ (x, y, z, w) = sb << "(" <+ x << ", " <+ y << ", " <+ z << ", " <+ w << ")"
1543     
1544 /// Tuple5 ///
1545
1546 instance (Ord a, Ord b, Ord c, Ord d, Ord e) => Ord (a, b, c, d, e) where
1547     compare (a0, b0, c0, d0, e0) (a1, b1, c1, d1, e1) = 
1548         compare a0 a1 &<& compare b0 b1 &<& compare c0 c1 &<& compare d0 d1 &<& compare e0 e1
1549     
1550 instance (Additive a, Additive b, Additive c, Additive d, Additive e) => Additive (a, b, c, d, e) where
1551     zero = (zero, zero, zero, zero, zero)
1552     (a0, b0, c0, d0, e0) + (a1, b1, c1, d1, e1) = (a0+a1, b0+b1, c0+c1, d0+d1, e0+e1)
1553
1554 instance Functor ((,,,,) a b c d) where
1555     fmap f (a,b,c,d,e) = (a, b, c, d, f e)
1556
1557 /// Lists ///
1558
1559 instance (Ord a) => Ord [a] where
1560     compare a b = loop 0 
1561       where
1562         lA = length a
1563         lB = length b
1564         loop i = if i >= lA
1565                  then (if i >= lB then 0 else -1)
1566                  else if i >= lB
1567                  then 1
1568                  else compare (a!i) (b!i) &<& loop (i+1)
1569
1570 instance Functor [] where
1571     fmap = mapList
1572
1573 instance FunctorE [] where
1574     map = mapEList
1575     iter = iterList
1576     iterI = iterIList
1577         
1578 instance Monad [] where
1579     return x = singletonList x
1580     l >>= f  = concatMap f l
1581     join l   = l >>= id
1582
1583 instance MonadZero [] where
1584     mzero = emptyList
1585
1586 instance MonadPlus [] where
1587     mplus = appendList
1588
1589 instance Additive [a] where
1590     zero = emptyList
1591     (+) = appendList
1592
1593 instance FunctorM [] where
1594     sequence = foldl (\m mel -> m >>= \l -> mel >>= \el -> return (addList l el)) (return emptyList)
1595     mapM f l = sequence (map f l)
1596
1597 "Appends the string representations of all elements of the list to the string builder and separates the values with the given separator."
1598 printWithSeparator :: Show a => StringBuilder.T -> String -> [a] -> <Proc> StringBuilder.T
1599 printWithSeparator sb sep l = loop 0
1600   where
1601     len = length l
1602     loop i = if i >= len then sb
1603              else do
1604                  (if i==0 then sb else sb << sep) <+ l!i
1605                  loop (i+1)
1606
1607 """
1608 Joins the string representations of the list of values with the given separator.
1609
1610 See [intercalate](#intercalate) for an alternative that works with Strings
1611 and doesn't escape its arguments.
1612 """
1613 joinWithSeparator :: Show a => String -> [a] -> String
1614 joinWithSeparator separator values = runProc ( 
1615     StringBuilder.toString $ printWithSeparator StringBuilder.new separator values)
1616
1617
1618 """
1619 The intercalate function takes a String and a list of Strings
1620 and concatenates the list after interspersing the first argument
1621 between each element of the list.
1622
1623 See also more generic [joinWithSeparator](#joinWithSeparator)
1624 which escapes its arguments using `show`.
1625 """
1626 intercalate :: String -> [String] -> String
1627 intercalate separator strings = do
1628     l = length strings
1629     if l == 0
1630     then ""
1631     else if l == 1
1632     then strings!0
1633     else runProc do
1634         sb = StringBuilder.new
1635         sb << strings!0
1636         loop i | i == l = ()
1637                | otherwise = do
1638             sb << separator << strings!i
1639             loop (i+1)
1640         loop 1
1641         StringBuilder.toString sb
1642
1643 instance (Show a) => Show [a] where
1644     sb <+ l = do 
1645         len = length l
1646         loop i = if i < len 
1647                  then do 
1648                      if (i>0) then sb << ", " else sb
1649                      sb <+ l!i
1650                      loop (i+1)
1651                  else sb << "]"
1652         sb << "[" 
1653         loop 0                 
1654
1655 importJava "java.util.List" where
1656     "`getList l i` returns the `i`th element of the list `l`. Indexing starts from zero. You can also use the `!` infix function for this purpose."
1657     @JavaName get
1658     getList :: [a] -> Integer -> a
1659
1660     @private
1661     @JavaName size
1662     lengthList :: [a] -> Integer
1663
1664     @private
1665     subList :: [a] -> Integer -> Integer -> [a]
1666
1667     @private
1668     isEmpty :: [a] -> Boolean
1669     
1670 @private    
1671 importJava "java.util.Collections" where
1672     emptyList :: [a]
1673     //singletonList :: a -> [a]
1674
1675 /*
1676 @inline
1677 emptyList :: [a]
1678 emptyList = build (\empty cons -> empty)
1679 */
1680
1681 "Creates a list with exectly one element."
1682 @inline
1683 singletonList :: a -> [a]
1684 singletonList v = build (\empty cons -> cons empty v)
1685
1686 /*
1687 // foldl f i (a + b) = foldl f (foldl f i a) b 
1688
1689 appendList :: [a] -> [a] -> [a]
1690 appendList a b = build (\empty cons -> foldl cons (foldl cons empty a) b)
1691 */
1692
1693 importJava "org.simantics.scl.runtime.list.ShareableList" where
1694     "Concatenates two lists."
1695     @private
1696     @JavaName "concat"
1697     appendList :: [a] -> [a] -> [a]
1698     
1699     "Adds the given value to the end of the list."
1700     @JavaName "add"   
1701     addList :: [a] -> a -> [a]
1702
1703 @private
1704 importJava "java.util.ArrayList" where
1705     data ArrayList a
1706
1707     @JavaName "<init>"
1708     newArrayList :: <Proc> ArrayList a
1709     
1710     @JavaName add
1711     addArrayList :: ArrayList a -> a -> <Proc> ()
1712
1713 """
1714 A primitive for constructing a list by `empty` and `cons` operations given to the function given as a parameter to this function.
1715 For example:
1716
1717     build (\empty cons -> cons (cons (cons empty 1) 2) 3)
1718     
1719 produces
1720
1721     [1, 2, 3]
1722     
1723 The SCL compiler makes the following optimization when encountering `build` and `foldl` functions after inlining:
1724
1725     foldl f i (build g) = g i f
1726 """
1727 @inline 2
1728 build :: forall b e2. (forall a e1. a -> (a -> b -> <e1> a) -> <e1,e2> a) -> <e2> [b]
1729 build f = runProc do
1730     l = newArrayList
1731     f () (\_ v -> addArrayList l v)
1732     Java.unsafeCoerce l
1733
1734 "A specific implementation of `map` for lists."
1735 @private
1736 @inline
1737 mapEList :: (a -> <e> b) -> [a] -> <e> [b]
1738 mapEList f l = build (\empty cons -> foldl (\cur x -> cons cur (f x)) empty l) 
1739
1740 "A specific implementation of `fmap` for lists."
1741 @inline
1742 mapList :: (a -> b) -> [a] -> [b]
1743 mapList f l = build (\empty cons -> foldl (\cur x -> cons cur (f x)) empty l) 
1744  
1745 "`guardList v` returns a singleton `[()]` if `v=True` and the empty list if `v=False`."
1746 @inline
1747 guardList :: Boolean -> [()]
1748 guardList cond = build (\empty cons -> if cond then cons empty () else empty) 
1749
1750 """
1751 `concatMap` combines `map` and `join` functions.
1752 It maps the elements of a given list to lists with the given function and concatenates the results.
1753
1754     concatMap f lst = join (map f lst) = [y | x <- lst, y <- f x] 
1755 """
1756 @inline
1757 concatMap :: (a -> <e> [b]) -> [a] -> <e> [b]
1758 concatMap f l = build (\empty cons -> foldl (\cur le -> foldl cons cur (f le)) empty l)
1759
1760 """
1761 Applies the given function to the elements of the lists until the function returns something
1762 else than `Nothing`. This return value is also returned as a result of this function.
1763 """
1764 @inline
1765 mapFirst :: (a -> <e> Maybe b) -> [a] -> <e> Maybe b
1766 mapFirst f l = loop 0 
1767   where
1768     len = length l
1769     loop i = if i == len
1770              then Nothing
1771              else match f (l!i) with
1772                  r @ (Just _) -> r
1773                  Nothing -> loop (i+1)
1774
1775 """
1776     foldl op initialValue list
1777     
1778 applies a binary operator `op` to all elements of `list` from left to right
1779 starting with `initialValue`. For example, 
1780
1781     foldl op init [x1, x2, x3, x4] = (((init `op` x1) `op` x2) `op` x3) `op` x4
1782 """
1783 @inline 2
1784 foldl :: forall a b e. (a -> b -> <e> a) -> a -> [b] -> <e> a
1785 foldl f initial l = loop initial 0
1786   where
1787     len = length l
1788     loop cur i = if i==len
1789                  then cur
1790                  else loop (f cur (l!i)) (i+1)
1791
1792 foldlI :: forall a b e. (Integer -> a -> b -> <e> a) -> a -> [b] -> <e> a
1793 foldlI f initial l = loop initial 0
1794   where
1795     len = length l
1796     loop cur i = if i==len
1797                  then cur
1798                  else loop (f i cur (l!i)) (i+1)
1799
1800 scanl :: (b -> a -> <e> b) -> b -> [a] -> <e> [b]
1801 scanl f initial l = build (\empty cons -> let
1802     len = length l
1803     loop cur i accum = let nl = cons accum cur
1804                            in if i==len
1805                            then nl
1806                             else loop (f cur (l!i)) (i+1) nl
1807   in loop initial 0 empty)
1808   
1809 "`foldr` is defined like `foldl` but it process the list from right to left."
1810 @inline
1811 foldr :: (b -> a -> <e> a) -> a -> [b] -> <e> a
1812 foldr f initial l = loop initial (length l - 1)
1813   where
1814     loop cur i = if i < 0
1815                  then cur
1816                  else loop (f (l!i) cur) (i-1)
1817
1818 foldr1 :: (a -> a -> <e> a) -> [a] -> <e> a
1819 foldr1 f l = loop (l!(len-1)) (len-2)
1820   where
1821     len = length l
1822     loop cur i = if i < 0
1823                  then cur
1824                  else loop (f (l!i) cur) (i-1)
1825
1826 """
1827 `filter pred lst` returns those elements of `lst` that the predicate `pred` accepts. For example
1828
1829     filter (> 3) [1, 2, 3, 4, 5, 6] = [4, 5, 6]
1830 """ 
1831 @inline
1832 filter :: (a -> <e> Boolean) -> [a] -> <e> [a]
1833 filter p l = build (\empty cons -> foldl (\cur x -> if p x then cons cur x else cur) empty l)
1834
1835 """
1836 Takes those elements of the input list that match `(Just x)` and adds the contents to the resulting list. For example,
1837
1838     filterJust [Just 1, Nothing, Just 5] = [1, 5] 
1839 """
1840 @inline
1841 filterJust :: [Maybe a] -> [a]
1842 filterJust l = build (\empty cons -> foldl (\cur x -> match x with Just v -> cons cur v ; _ -> cur) empty l)
1843
1844 listToMaybe :: [a] -> Maybe a
1845 listToMaybe l = if isEmpty l then Nothing else Just (l!0)
1846
1847 maybeToList :: Maybe a -> [a]
1848 maybeToList (Just a) = [a]
1849 maybeToList _ = [] 
1850
1851 """
1852 `takeWhile p l`, returns the longest prefix (possibly empty) of list `l` of elements that satisfy `p`
1853 """
1854 takeWhile :: (a -> <e> Boolean) -> [a] -> <e> [a]
1855 takeWhile f l = loop 0 
1856   where
1857     len = length l
1858     loop i | i == len  = l
1859            | f (l!i)   = loop (i+1)
1860            | otherwise = take i l
1861
1862 partition :: (a -> <e> Boolean) -> [a] -> <e> ([a], [a])
1863 partition p l = runProc do
1864     res1 = newArrayList
1865     res2 = newArrayList
1866     for l (\el ->
1867         if p el
1868         then addArrayList res1 el
1869         else addArrayList res2 el
1870     )
1871     (Java.unsafeCoerce res1, Java.unsafeCoerce res2)
1872
1873 """
1874 `range begin end` produces a list of consecutive integers starting from `begin` and ending to `end` (including `end`).
1875 The compiler supports syntactic sugar `[begin..end]` for this function.
1876 """
1877 @inline    
1878 range :: Integer -> Integer -> [Integer]
1879 range first last = build (\empty cons -> do
1880     loop i cur = if i > last then cur else loop (i+1) (cons cur i)
1881     loop first empty)
1882
1883 "A specific implementation of `iter` for lists."
1884 @inline
1885 iterList :: (a -> <e> b) -> [a] -> <e> ()
1886 iterList f l = foldl (\_ x -> ignore (f x)) () l
1887
1888 "A specific implementation of `iterI` for lists."
1889 @inline
1890 iterIList :: (Integer -> a -> <e> b) -> [a] -> <e> ()
1891 iterIList f l = do foldl (\i x -> do f i x ; i+1) 0 l ; () 
1892
1893 """
1894 Generates a list from a given starting state and iteration function.
1895 For example
1896
1897     let nextState 0 = Nothing
1898         nextState i = Just (i, i `div` 2)
1899     in  unfoldr nextState 30
1900         
1901 produces
1902
1903     [30, 15, 7, 3, 1]
1904 """
1905 @inline
1906 unfoldr :: (b -> <e> Maybe (a, b)) -> b -> <e> [a]
1907 unfoldr f s = build (\empty cons -> do
1908     loop s cur =
1909         match f s with
1910             Just (el,newS) -> loop newS (cons cur el)
1911             _ -> cur
1912     loop s empty)
1913
1914 importJava "org.simantics.scl.runtime.Lists" where
1915     /*
1916     @private
1917     @JavaName map
1918     mapList :: (a -> b) -> [a] -> [b]    
1919     @private
1920     @JavaName map
1921     mapEList :: (a -> <e> b) -> [a] -> <e> [b]
1922     @private
1923     @JavaName iter
1924     iterList :: (a -> <e> ()) -> [a] -> <e> ()
1925     concatMap :: (a -> <e> [b]) -> [a] -> <e> [b]
1926     */ 
1927     """
1928     Combines two lists into one list of pairs. The length of the resulting list is the length of the smallest input list.
1929     
1930         zip [1, 2, 3, 4, 5] ['a', 'b', 'c'] = [(1, 'a'), (2, 'b'), (3, 'c')]
1931     """
1932     zip :: [a] -> [b] -> [(a,b)]
1933     "Combines two lists by using the given function for combining the elements. The length of the resulting list is the length of the smallest input list."
1934     zipWith :: (a -> b -> <e> c) -> [a] -> [b] -> <e> [c]
1935     """
1936     Produces two lists from one list of pairs.
1937     
1938         unzip [(1, 'a'), (2, 'b'), (3, 'c')] = ([1, 2, 3], ['a', 'b', 'c'])
1939     """
1940     unzip :: [(a,b)] -> ([a],[b])
1941     
1942     //"@filter p l@ returns those elements of @l@ that the predicate @p@ accepts." 
1943     //filter :: (a -> <e> Boolean) -> [a] -> <e> [a]
1944     //filterJust :: [Maybe a] -> [a]
1945     /*
1946     foldl :: (a -> b -> <e> a) -> a -> [b] -> <e> a
1947     */
1948     "Like `foldl` but assumes that the list is non-empty so the initial is not needed."
1949     foldl1 :: (a -> a -> <e> a) -> [a] -> <e> a
1950     //unfoldr :: (b -> <e> Maybe (a, b)) -> b -> <e> [a]
1951     
1952     "Sorts the list using the given comparator."
1953     sortWith :: (a -> a -> <e> Integer) -> [a] -> <e> [a]
1954     
1955     """
1956     Given a list of key-value pairs, the function produces a function that finds a value
1957     efficiently for the given key.
1958     """
1959     index :: [(a,b)] -> a -> Maybe b
1960     
1961     """
1962     Given a list of values and a function computing a key for each value, the function produces a function that finds a value
1963     effeciently for the given key.
1964     """
1965     indexBy ::  (a -> <e> b) -> [a] -> <e> (b -> Maybe a)
1966     
1967     "Works like `index` but uses the given functions as hash codes and equality."
1968     indexWith :: (a -> Integer) -> (a -> a -> Boolean) -> [(a,b)] -> a -> Maybe b
1969     
1970     "Groups a list values by a key computed by the given function."
1971     groupBy :: (a -> <e> b) -> [a] -> <e> [(b, [a])]
1972     
1973     "Groups a list of key-value pairs by the keys."
1974     group :: [(a,b)] -> [(a, [b])]
1975
1976     "Composition of index and groupBy."
1977     indexGroupBy :: (a -> <e> b) -> [a] -> <e> (b -> [a])
1978     
1979     "Composition of index and group."
1980     indexGroup :: [(a,b)] -> a -> [b]
1981     
1982     groupWith :: (b -> Integer) -> (b -> b -> Boolean) -> (a -> <e> b) -> (a -> <e> c) -> [a] -> <e> [(b, [c])]
1983     
1984     "Removes duplicates (all but the first occurrence) from the list but otherwise preserves the order of the elements."
1985     unique :: [a] -> [a]
1986     
1987     "Like `unique`, but uses the given function for finding the key values used for uniqueness testing."
1988     uniqueBy :: (a -> b) -> [a] -> [a]
1989
1990     "Works like `unique` but uses the given function for equality tests."
1991     uniqueWith :: (a -> a -> Boolean) -> [a] -> [a]
1992     
1993     "Works like `\\\\` but uses the given function for equality tests."
1994     deleteAllBy :: (a -> a -> Boolean) -> [a] -> [a] -> [a]
1995     
1996     @private
1997     listDifference :: [a] -> [a] -> [a]
1998     
1999     //range :: Integer -> Integer -> [Integer]
2000     
2001     //build :: (forall a. a -> (a -> b -> <e> a) -> <e> a) -> <e> [b]
2002
2003 "`elem el lst` return true, if `el` occurs in the list `lst`."
2004 elem :: a -> [a] -> Boolean
2005 elem el l = loop 0
2006   where
2007     len = length l
2008     loop i | i < len = if el == l!i
2009                        then True
2010                        else loop (i+1)
2011            | otherwise = False
2012
2013 "`elemMaybe v1 (Just v2)` returns true if `v1 == v2`. `elemMaybe v1 Nothing` is always false."
2014 elemMaybe :: a -> Maybe a -> Boolean
2015 elemMaybe el m = match m with
2016     Just el2 -> el == el2
2017     Nothing -> False
2018
2019 "`elemIndex el lst` returns the index of the first element in the given list `lst` which is equal (by ==) to the query element, or Nothing if there is no such element."
2020 elemIndex :: a -> [a] -> Maybe Integer
2021 elemIndex el l = loop 0
2022   where
2023     len = length l
2024     loop i | i < len = if el == l!i
2025                        then Just i
2026                        else loop (i+1)
2027            | otherwise = Nothing
2028
2029 """
2030 Computes a list that contains only elements that belongs to both input lists.
2031 """
2032 intersect :: [a] -> [a] -> [a]
2033 intersect a b = filter f a
2034   where
2035     f e = elem e b
2036
2037 "Reverses a given list. For example, `reverse [1,2,3] = [3,2,1]`"
2038 reverse :: [a] -> [a]
2039 reverse l = [l!(len-i) | i <- [1..len]]
2040   where
2041     len = length l
2042
2043 """
2044 Transposes the rows and columns of its argument. For example,
2045
2046     transpose [[1,2,3],[4,5,6]] == [[1,4],[2,5],[3,6]]
2047     transpose [[1,2],[3,4,5]] == [[1,3],[2,4],[5]]
2048 """
2049 transpose xss = [[xs!i | xs <- xss, i < length xs]
2050                 | i <- [0..maximum [length xs | xs <- xss]-1]]
2051
2052 "Works like `unfoldr` but generates the list from right to left."
2053 unfoldl :: (b -> <e> Maybe (a, b)) -> b -> <e> [a]
2054 unfoldl f seed = reverse $ unfoldr f seed
2055
2056 "Removes the first element of the list, if the list is non-empty."
2057 tail :: [a] -> [a]
2058 tail l = if len < 2 then emptyList else subList l 1 len 
2059   where 
2060     len = length l
2061
2062 "Tries to find the given key from the list of key-value pairs and returns the corresponding value."
2063 lookup ::  a -> [(a, b)] -> Maybe b
2064 lookup el l = do
2065     len = length l
2066     loop i = if i < len 
2067              then match l!i with
2068                (a,b) | a == el   -> Just b
2069                      | otherwise -> loop (i+1)
2070              else Nothing
2071     loop 0
2072
2073 "Conjunction over a list."
2074 @inline
2075 and :: [Boolean] -> Boolean
2076 and = foldl (&&) True
2077
2078 "Disjunction over a list."
2079 @inline
2080 or :: [Boolean] -> Boolean
2081 or  = foldl (||) False
2082
2083 """
2084 `any pred lst` tests whether the predicate `pred` holds some element of `lst`.
2085 It returns immediately when it encounters the first value satisfying the predicate.
2086 """ 
2087 any :: (a -> <e> Boolean) -> [a] -> <e> Boolean
2088 any p =  or . map p
2089
2090 """
2091 `all pred lst` tests whether the predicate `pred` holds for all elements of `lst`.
2092 It returns immediately when it encounters the first value not satisfying the predicate.
2093 """ 
2094 all :: (a -> <e> Boolean) -> [a] -> <e> Boolean
2095 all p =  and . map p
2096
2097 """
2098 Returns the first element of the list satisfying the given condition,
2099 or `Nothing` if there is no such element.
2100 """
2101 findFirst :: (a -> <e> Boolean) -> [a] -> <e> Maybe a
2102 findFirst p l = loop 0
2103   where
2104     len = length l
2105     loop i = if i < len 
2106              then let el = l!i in 
2107                   if p el 
2108                   then Just el 
2109                   else loop (i+1)
2110              else Nothing
2111     loop 0
2112
2113
2114 """
2115 Sorts the given list using its default order.
2116 """
2117 @inline
2118 sort :: Ord a => [a] -> [a]
2119 sort = sortWith compare
2120
2121 """
2122 Sorts the lists by the values computed by the first function.
2123 For example
2124
2125     sortBy snd [(1,5), (2,3), (3,4)] = [(2,3), (3,4), (1,5)] 
2126 """
2127 @inline
2128 sortBy :: Ord b => (a -> <e> b) -> [a] -> <e> [a]
2129 sortBy f l = sortWith (\x y -> compare (f x) (f y)) l
2130 // This is faster if f is slow, but will generate more auxiliary structures
2131 //sortBy f l = map snd (sortWith (\(x,_) (y,_) -> compare x y) [(f x, x) | x <- l])
2132
2133 "`a \\\\ b` removes all elements of `b` from the list `a`."
2134 (\\) :: [a] -> [a] -> [a]
2135 (\\) = listDifference
2136
2137 /// Dynamic ///
2138
2139 importJava "java.lang.Object" where
2140     "A data type that can represent any value."
2141     data Dynamic
2142     
2143     @private
2144     @JavaName toString
2145     showDynamic :: Dynamic -> String
2146
2147 instance Show Dynamic where
2148     show = showDynamic
2149
2150 "Converts a value to `Dynamic` type."
2151 toDynamic :: a -> Dynamic
2152 toDynamic = Java.unsafeCoerce
2153
2154 "Converts a `Dynamic` value to a required value, or fails if the conversion is not possible."
2155 importJava "org.simantics.scl.compiler.runtime.ValueConversion" where
2156     fromDynamic :: Typeable a => Dynamic -> a
2157
2158 /// Procedures ///
2159
2160 importJava "org.simantics.scl.runtime.procedure.Ref" where
2161     "A mutable reference to a value of type `a`."
2162     data Ref a
2163     
2164     "Creates a new reference with the given initial value."
2165     @JavaName "<init>"
2166     ref :: a -> <Proc> (Ref a)
2167     
2168     "Returns the current value of the reference."
2169     @JavaName "value"
2170     getRef :: Ref a -> <Proc> a
2171     
2172     "Sets a new value for the reference."
2173     @JavaName "<set>value"
2174     (:=) :: Ref a -> a -> <Proc> ()
2175
2176 instance Show (Ref a) where
2177     show _ = "<reference>"
2178
2179 importJava "org.simantics.scl.runtime.reporting.SCLReporting" where
2180     "Prints the given string to the console."
2181     @JavaName "print"
2182     printString :: String -> <Proc> ()
2183     "Prints an error message to the console."
2184     printError :: String -> <Proc> ()
2185     "Reports that certain amount of work has been done for the current task."
2186     didWork :: Double -> <Proc> ()
2187     """
2188     `printingToFile "fileName" expression` executes the `expression` so that all its console prints
2189     are written to the file given as a first parameter.
2190     """
2191     printingToFile :: String -> (<e> a) -> <e> a
2192     """
2193     `printErrorsAsNormalPrints expression` executes the `expression` so that all its error prints
2194     are printed as normal prints. This is useful mainly in testing scripts for checking that the implementations
2195     give proper error messages with invalid inputs.
2196     """
2197     printErrorsAsNormalPrints :: (<e> a) -> <e> a
2198     """
2199     `disablePrintingForCommand expression` executes the `expression` so that it does not print return values.
2200     Errors are printed normally.
2201     """
2202     disablePrintingForCommand :: (<e> a) -> <e> a
2203     
2204
2205 importJava "org.simantics.scl.runtime.procedure.Procedures" where
2206     "Returns `True` if the current thread has been interrupted."
2207     isInterrupted :: <Proc> Boolean
2208     "Checks whether the current thread has been interrupted and throws an exception if it is."
2209     checkInterrupted :: <Proc> ()
2210     "Generates a random identifier."
2211     generateUID :: <Proc> String
2212     
2213     "Executes the given expression and catches certain class of exceptions (specified by the catch handler that is given as a second parameter.)"
2214     @JavaName catch_
2215     catch :: VecComp ex => (<e,Exception> a) -> (ex -> <e> a) -> <e> a
2216
2217 importJava "java.lang.Throwable" where
2218     data Throwable
2219     @private
2220     @JavaName toString
2221     showThrowable :: Throwable -> String
2222     @private
2223     @JavaName getMessage 
2224     getMessageThrowable :: Throwable -> String
2225     @private
2226     @JavaName getCause 
2227     getCauseThrowable :: Throwable -> Maybe Throwable
2228 importJava "java.lang.Exception" where
2229     data Exception
2230     @private
2231     @JavaName toString
2232     showException :: Exception -> String
2233
2234 instance Show Throwable where
2235     show = showThrowable
2236 instance Show Exception where
2237     show = showException
2238
2239 class Throwable e where
2240     toThrowable :: e -> Throwable
2241
2242 messageOfException :: Throwable e => e -> String
2243 messageOfException = getMessageThrowable . toThrowable
2244
2245 causeOfException :: Throwable e => e -> Maybe Throwable
2246 causeOfException = getCauseThrowable . toThrowable
2247
2248 instance Throwable Throwable where
2249     toThrowable = id
2250 instance Throwable Exception where
2251     toThrowable = Java.unsafeCoerce
2252
2253 "Prints the given value in the console."
2254 @inline
2255 print :: Show a => a -> <Proc> ()
2256 print v = printString (showForPrinting v)
2257 /*
2258 instance Show TypeRep where
2259     sb <+ (TApply (TCon "Builtin" "[]") b) = 
2260         sb << "[" <+ b << "]"
2261     sb <+ (TApply (TApply (TCon "Builtin" "(,)") c1) c2) = 
2262         sb << "(" <+ c1 << "," <+ c2 << ")"
2263     sb <+ (TApply (TApply (TApply (TCon "Builtin" "(,,)") c1) c2) c3) = 
2264         sb << "(" <+ c1 << "," <+ c2 << "," <+ c3 << ")"
2265     sb <+ (TApply (TApply (TApply (TApply (TCon "Builtin" "(,,,)") c1) c2) c3) c4) =
2266         sb << "(" <+ c1 << "," <+ c2 << "," <+ c3 << "," <+ c4 << ")" 
2267     
2268     sb <+ (TCon _ name) = sb << name
2269     sb <+ (TApply a b) = sb <+ Par 1 a << " " <+ Par 2 b
2270     sb <+ (TFun a b) = sb <+ Par 1 a << " -> " <+ b
2271     
2272     precedence (TCon _ _) = 0
2273     precedence (TFun _ _) = 2
2274     precedence (TApply a _) = if isSpecialType a then 0 else 1
2275       where
2276         isSpecialType (TCon "Builtin" "[]") = True
2277         isSpecialType (TCon "Builtin" "()") = True
2278         isSpecialType (TCon "Builtin" "(,)") = True
2279         isSpecialType (TCon "Builtin" "(,,)") = True
2280         isSpecialType (TCon "Builtin" "(,,,)") = True
2281         isSpecialType (TApply a _) = isSpecialType a
2282 */
2283
2284 // ByteArray
2285
2286 importJava "java.util.Arrays" where
2287     @private
2288     @JavaName toString
2289     byteArrayToString :: ByteArray -> String
2290
2291 instance Show ByteArray where
2292     show = byteArrayToString
2293
2294 // Type
2295
2296 @private
2297 importJava "org.simantics.scl.compiler.types.Type" where
2298     @JavaName toString
2299     showType :: Type -> String
2300
2301 importJava "org.simantics.scl.compiler.types.Types" where
2302     removeForAll :: Type -> Type
2303     
2304 instance Show Type where
2305     show = showType