]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.runtime/scl/Prelude.scl
Improve joinWithSeparator and intercalate documentation
[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 "While loop. `while cond body` executes the `body` while the `cond` is true." 
925 @inline
926 while :: (<e> Boolean) -> (<e> a) -> <e> ()
927 while cond body = loop ()
928   where loop _ = if cond 
929                  then do body ; loop ()
930                  else ()
931
932 """
933 Sequences the given monadic value infinitely:
934
935     repeatForever m = m >> m >> m >> ...
936 """
937 repeatForever m = m >> repeatForever m
938
939 replicateM :: Monad m => Integer -> m a -> m [a]
940 replicateM count m = loop count emptyList
941   where
942     loop count l | count <= 0 = return l
943                  | otherwise  = mdo
944                      v <- m
945                      loop (count-1) (addList l v)
946
947 replicateM_ :: Monad m => Integer -> m a -> m ()
948 replicateM_ count m | count <= 0 = return ()
949                     | otherwise  = m >> replicateM_ (count-1) m
950
951 /// MonadZero ///
952
953 """
954 A class of monads with zero element satisfying
955
956     mzero >>= f = mzero
957 """ 
958 class (Monad m) => MonadZero m where
959     mzero :: m a
960
961 "Injects a boolean test to a type beloning to `MonadZero`."
962 guard :: MonadZero m => Boolean -> m ()
963 guard True = return ()
964 guard False = mzero
965
966 /// MonadPlus ///
967
968 """
969 A class of monads with associative binary operator `mplus` satisfying the following laws:  
970
971     mplus mzero b = b
972     mplus a mzero = a
973     mplus (mplus a b) c = mplus a (mplus b c)
974     mplus a b >>= k = mplus (a >>= k) (b >>= k)
975 """
976 class (MonadZero m) => MonadPlus m where
977     mplus :: m a -> m a -> m a
978
979 /// MonadOr ///
980
981 """
982 A class of monads with associative binary operator `morelse` satisfying the following laws:  
983
984     morelse mzero b = b
985     morelse a mzero = a
986     morelse (morelse a b) c = morelse a (morelse b c)
987     morelse (return a) b = return a
988 """
989 class (MonadZero m) => MonadOr m where
990     morelse :: m a -> m a -> m a
991
992 /// FunctorE ///
993
994 """
995 A class of types that can be mapped over with effectful mapping functions.
996 """
997 class (Functor f) => FunctorE f where
998     """
999     Applies the function to all elements of the container and
1000     returns the similarly shaped container with the results:
1001     
1002     For lists,
1003     
1004         map f [e1, e2, ..., eN] = [f e1, f e2, ..., f eN]
1005         
1006     for example
1007     
1008         map (*2) [1..5] = [2, 4, 6, 8, 10]
1009     """
1010     map :: (a -> <e> b) -> f a -> <e> (f b)
1011     "Calls the given function with all elements of the given container."
1012     iter :: (a -> <e> b) -> f a -> <e> ()
1013     "Calls the given function with all elements of the given container giving also the index of the element as a parameter."
1014     iterI :: (Integer -> a -> <e> b) -> f a -> <e> ()
1015
1016 "Iterates the elements of the given collection. Same as `iter` but parameters flipped." 
1017 for :: FunctorE f => f a -> (a -> <e> b) -> <e> ()
1018 @macro
1019 for l f = iter f l
1020
1021 "Iterates the elements of the given collection providing also the indices of the elements. Same as `iterI` but parameters flipped." 
1022 forI :: FunctorE f => f a -> (Integer -> a -> <e> b) -> <e> ()
1023 @macro
1024 forI l f = iterI f l
1025
1026 "`forN n f` calls `f` for all integers `0`, ..., `n-1`"
1027 @inline
1028 forN :: Integer -> (Integer -> <e> b) -> <e> ()
1029 forN n f = loop 0
1030   where
1031     loop i = if i < n
1032              then do f i ; loop (i+1)
1033              else ()
1034
1035 @inline
1036 mapI :: (Integer -> a -> <e> b) -> [a] -> <e> [b]
1037 mapI f l = build (\empty cons -> let
1038     len = length l
1039     loop i accum = if i < len
1040                    then loop (i+1) (cons accum (f i (l!i)))
1041                    else accum
1042   in loop 0 empty)
1043
1044 """
1045 `mapMaybe` combines `map` and `filter` functions. 
1046 It applies the given function to every element of the input list. If the result
1047 is `Just x`, then `x` is added to the resulting list.
1048
1049     mapMaybe f lst = [y | x <- lst, Just y = f x]
1050 """
1051 @inline
1052 mapMaybe :: (a -> <e> Maybe b) -> [a] -> <e> [b]
1053 mapMaybe f l = build (\empty cons -> foldl (\cur x -> match f x with Just v -> cons cur v ; _ -> cur) empty l)
1054
1055 """
1056 Applies the given function to all elements of the list. Produces two lists: the first contains all elements `x`
1057 for which the function returned `Left x` and the second list contains all elements `y` for which the function
1058 returned `Right y`.
1059 """
1060 mapEither :: (a -> <e> Either b c) -> [a] -> <e> ([b], [c])
1061 mapEither f list = runProc do
1062     l = newArrayList
1063     r = newArrayList
1064     for list (\x -> match f x with
1065         Left v -> addArrayList l v
1066         Right v -> addArrayList r v)
1067     (Java.unsafeCoerce l, Java.unsafeCoerce r)
1068
1069 "`replicate n v` returns a list of length `n` such that each element is a copy of `v`."
1070 @inline
1071 replicate :: Integer -> a -> [a]
1072 replicate n v = build (\empty cons ->
1073     let aux 0 l = l
1074         aux i l = aux (i-1) (cons l v)
1075     in aux n empty 
1076     )
1077
1078 /// FunctorM ///
1079
1080 class (Functor f) => FunctorM f where
1081     "`mapM f` is equivalent to `sequence . map f`."
1082     mapM :: Monad m => (a -> m b) -> f a -> m (f b)
1083     "Evaluate each action in the sequence from left to right, and collect the results."
1084     sequence :: Monad m => f (m a) -> m (f a) 
1085     mapM f l = sequence (fmap f l)
1086
1087 /// Category ///
1088
1089 "Identity function."
1090 id :: a -> a
1091 id x = x
1092
1093 """
1094 Ignores the given value. This function is used in a situation where a function returns
1095 a value in a context where the value is not expected.
1096 """
1097 @inline
1098 ignore :: a -> ()
1099 ignore _ = ()
1100
1101 @inline
1102 ignoreM :: a -> Maybe b
1103 ignoreM _ = Nothing
1104
1105 """
1106 Composes two functions
1107     (f . g) x = f (g x)
1108 """
1109 (.) :: (b -> <e> c) -> (a -> <e> b) -> (a -> <e> c)
1110 (f . g) x = f (g x)
1111
1112 /// Sequence ///
1113
1114 "A type class for sequences. All sequences must support indexing by integers."
1115 class /*(Additive a) =>*/ Sequence a where
1116     "Length of the sequence"
1117     length :: a -> Integer
1118     "`take n s` returns the first `n` elements of the sequence `s`."
1119     take :: Integer -> a -> a
1120     "`drop n s` removes the first `n` elements of the sequence `s`."
1121     drop :: Integer -> a -> a
1122     """
1123     `sub s begin end` returns a subsequence of `s` starting from
1124     index `begin` and ending just before index `end`.
1125     """ 
1126     sub :: a -> Integer -> Integer -> a
1127     
1128     take n v = sub v 0 (min n (length v))
1129     drop n v = sub v (min n len) len
1130       where
1131         len = length v 
1132
1133 instance Sequence [a] where
1134     length = lengthList
1135     sub = subList
1136     
1137 instance Sequence String where
1138     length = lengthString
1139     sub = subString        
1140
1141 class IndexedSequence f where
1142     "`seq ! i` returns the `i`th element of the sequence `seq`. Indexing starts from zero."
1143     (!) :: f a -> Integer -> a
1144
1145 instance IndexedSequence [] where
1146     (!) = getList
1147
1148 /// Boolean ///
1149
1150 """
1151 Equivalent to the boolean value `True`. The value is meant to be used in
1152 guard patterns:
1153
1154     min a b | a < b     = a
1155             | otherwise = b 
1156 """
1157 @inline
1158 otherwise :: Boolean
1159 otherwise = True
1160
1161 instance Ord Boolean where
1162     compare False False = 0
1163     compare False True  = neg 1
1164     compare True  False = 1
1165     compare True  True  = 0
1166
1167 instance Show Boolean where
1168     show True = "True"
1169     show False = "False"
1170
1171 """
1172 Boolean conjunction (and). The function is a macro that evaluates the second parameter
1173 only if the first parameter is `True`.
1174
1175 <table>
1176 <tr><th>a</th><th>b</th><th>a && b</th></tr>
1177 <tr><td>True</td><td>True</td><td>True</td></tr>
1178 <tr><td>True</td><td>False</td><td>False</td></tr>
1179 <tr><td>False</td><td>not evaluated</td><td>False</td></tr>
1180 </table> 
1181 """
1182 @macro
1183 (&&) :: Boolean -> Boolean ->  Boolean
1184 a && b = if a then b else False
1185
1186 """
1187 Boolean disjunction (or). The function is a macro that evaluates the second parameter
1188 only if the first parameter is `False`.
1189
1190 <table>
1191 <tr><th>a</th><th>b</th><th>a || b</th></tr>
1192 <tr><td>True</td><td>not evaluated</td><td>True</td></tr>
1193 <tr><td>False</td><td>True</td><td>True</td></tr>
1194 <tr><td>False</td><td>False</td><td>False</td></tr>
1195 </table> 
1196 """
1197 @macro
1198 (||) :: Boolean -> Boolean -> Boolean
1199 a || b = if a then True else b
1200
1201 "Boolean negation"
1202 @inline
1203 not a = if a then False else True
1204
1205 /// Maybe ///
1206
1207 //data Maybe a = Nothing | Just a
1208
1209 "Given `Just x` this function returns `x`. If the parameter is `Nothing`, the function raises an exception."
1210 fromJust :: Maybe a -> a
1211 fromJust (Just a) = a
1212
1213 deriving instance (Ord a) => Ord (Maybe a)
1214 deriving instance (Show a) => Show (Maybe a)
1215
1216 instance Functor Maybe where
1217     fmap _ Nothing  = Nothing
1218     fmap f (Just x) = Just (f x)
1219
1220 instance FunctorE Maybe where
1221     map _ Nothing  = Nothing
1222     map f (Just x) = Just (f x)
1223     
1224     iter _ Nothing = ()
1225     iter f (Just x) = ignore (f x)
1226     
1227     iterI _ Nothing = ()
1228     iterI f (Just x) = ignore (f 0 x)
1229     
1230 instance Monad Maybe where    
1231     return x = Just x
1232
1233     @inline
1234     Nothing >>= _ = Nothing
1235     Just x  >>= f = f x
1236
1237     @inline
1238     join Nothing  = Nothing
1239     join (Just x) = x
1240
1241 instance MonadZero Maybe where
1242     mzero = Nothing
1243
1244 instance MonadOr Maybe where
1245     morelse a@(Just _) _ = a
1246     morelse _ b = b
1247
1248 "`execJust v f` executes the function `f` with parameter value `x`, if `v=Just x`. If `v=Nothing`, the function does nothing."
1249 @inline
1250 execJust :: Maybe a -> (a -> <e> b) -> <e> ()
1251 execJust maybeValue procedure = match maybeValue with
1252     Just v -> ignore $ procedure v
1253     _ -> ()
1254
1255 "`fromMaybe def v` returns `def` if `v=Nothing` and `x` if `v=Just x`."
1256 @inline
1257 fromMaybe :: a -> Maybe a -> a
1258 fromMaybe default maybeValue = match maybeValue with
1259     Just v -> v
1260     _ -> default
1261     
1262     
1263 """
1264 Provides a default value if the first parameter is Nothing.
1265 The default value is evaluated only if needed. The function
1266 can be used as an operator and is right associative so that
1267 the following is possible:
1268
1269     tryWithTheFirstMethod
1270         `orElse` tryWithTheSecondMethod
1271         `orElse` fail "Didn't succeed."
1272 """
1273 @inline
1274 orElse :: Maybe a -> (<e> a) -> <e> a
1275 orElse (Just x) _   = x
1276 orElse Nothing  def = def
1277
1278 /// Either ///
1279
1280 """
1281 The Either type represents values with two possibilities: a value of type `Either a b` is either `Left a` or `Right b`.
1282
1283 The `Either` type is sometimes used to represent a value which is either correct or an error; by convention, the `Left` constructor
1284 is used to hold an error value and the `Right` constructor is used to hold a correct value (mnemonic: "right" also means "correct").
1285 """
1286 @JavaType "org.simantics.scl.runtime.either.Either"
1287 data Either a b =
1288     @JavaType "org.simantics.scl.runtime.either.Left"
1289     @FieldNames [value]
1290     Left a
1291   | @JavaType "org.simantics.scl.runtime.either.Right"
1292     @FieldNames [value]
1293     Right b
1294
1295 deriving instance (Ord a, Ord b) => Ord (Either a b)
1296 deriving instance (Show a, Show b) => Show (Either a b)
1297
1298 instance Functor (Either a) where
1299     fmap _ (Left x)  = Left x
1300     fmap f (Right y) = Right (f y)
1301
1302 instance FunctorE (Either a) where
1303     map _ (Left x)  = Left x
1304     map f (Right y) = Right (f y)
1305     
1306     iter _ (Left x) = ()
1307     iter f (Right y) = ignore (f y)
1308     
1309     iterI _ (Left x) = ()
1310     iterI f (Right y) = ignore (f 0 y)
1311         
1312 instance Monad (Either b) where
1313     return y = Right y
1314
1315     Left x  >>= _ = Left x
1316     Right y >>= f = f y
1317
1318     join (Left x)  = Left x
1319     join (Right y) = y
1320     
1321 /// String ///
1322
1323 importJava "java.lang.String" where
1324     @private
1325     @JavaName "concat"
1326     concatString :: String -> String -> String
1327     @private
1328     @JavaName "compareTo"
1329     compareString :: String -> String -> Integer
1330     @private
1331     @JavaName "length"
1332     lengthString :: String -> Integer
1333
1334     """
1335     `replaceString original pattern replacement` replaces all occurrences of `pattern` in the string by `replacement`.
1336     """ 
1337     @JavaName replace
1338     replaceString :: String -> String -> String -> String
1339     
1340     @private
1341     @JavaName split
1342     splitString_ :: String -> String -> Array String
1343     
1344     """
1345     `indexOf string s` finds the first occurrence of `s` from `string` and returns its index.
1346     If the `s` does not occur in the string, return `-1`."
1347     """
1348     @JavaName indexOf
1349     indexOf :: String -> String -> Integer
1350     
1351     "Works like `indexOf` but starts searching from the given index instead of the beginning of the string."
1352     @JavaName indexOf
1353     indexOfStartingFrom :: String -> String -> Integer -> Integer
1354     
1355     "Works like `indexOf` but returns the index of the last occurrence."
1356     @JavaName lastIndexOf
1357     lastIndexOf :: String -> String -> Integer
1358     
1359     "Works like `lastIndexOf` but starts searching from the given index instead of the end of the string."
1360     @JavaName lastIndexOf
1361     lastIndexOfStartingFrom :: String -> String -> Integer -> Integer
1362     
1363     @private
1364     @JavaName substring
1365     subString :: String -> Integer -> Integer -> String
1366
1367     """
1368     `regionMatches str1 offset1 str2 offset2 len` tests whether
1369     `sub str1 offset1 (offset1+len) == sub str2 offset2 (offset2+len)`.
1370     """
1371     regionMatches :: String -> Integer -> String -> Integer -> Integer -> Boolean
1372
1373     "`startsWith string prefix` returns true if the string begins with the given prefix."
1374     startsWith :: String -> String -> Boolean
1375     
1376     "`endsWith string suffix` returns true if the string ends with the given prefix."
1377     endsWith :: String -> String -> Boolean
1378     
1379     "Removes leading and trailing whitespace from the string."
1380     trim :: String -> String
1381     
1382     "`contains string s` returns true if `string` contains `s` as a substring."
1383     contains :: String -> String -> Boolean
1384     
1385     "`charAt string i` returns the `i`th character of the string."
1386     charAt :: String -> Integer -> Character
1387     
1388     "Converts all letters of the string to lower case."
1389     toLowerCase :: String -> String
1390     "Converts all letters of the string to upper case."
1391     toUpperCase :: String -> String
1392     
1393     "Creates a string from a vector of characters."
1394     @JavaName "<init>"
1395     string :: Vector Character -> String
1396
1397 instance Ord String where
1398     compare = compareString
1399     
1400 instance Additive String where
1401     zero = ""
1402     (+) = concatString
1403     sum ss = runProc (StringBuilder.toString $ foldl StringBuilder.appendString StringBuilder.new ss)
1404
1405 @private
1406 importJava "org.simantics.scl.runtime.string.StringEscape" where
1407     appendEscapedString :: StringBuilder.T -> String -> <Proc> StringBuilder.T
1408
1409 instance Show String where
1410     showForPrinting = id
1411     sb <+ v = (appendEscapedString (sb << "\"") v) << "\""
1412
1413 instance Read String where
1414     read str = str
1415     
1416 @deprecated "Instead of 'splitString text pattern', write 'split pattern text' (note change in the parameter order)." 
1417 "`splitString text pattern` splits the string into a list of string where the parts are sepratated in the original list by the given pattern."
1418 splitString :: String -> String -> [String]
1419 splitString source pattern = arrayToList $ splitString_ source pattern
1420
1421 """
1422 `split pattern text` splits `text` around matches of the given regular expression `pattern`.
1423
1424 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.
1425
1426 The string "boo:and:foo", for example, yields the following results with these expressions:
1427
1428     Regex   Result
1429     :       { "boo", "and", "foo" }
1430     o       { "b", "", ":and:f" }
1431 """
1432 split :: String -> String -> [String]
1433 split pattern text = arrayToList $ splitString_ text pattern
1434
1435 /// Tuple0 ///
1436
1437 instance Ord () where
1438     compare () () = 0
1439
1440 instance Additive () where
1441     zero = ()
1442     () + () = ()
1443
1444 instance Show () where
1445     show () = "()"
1446
1447 /// Tuple2 ///
1448
1449 "Gives the first element of a pair."
1450 @inline
1451 fst :: (a,b) -> a
1452 fst (x,y) = x
1453
1454 "Gives the second element of a pair."
1455 @inline
1456 snd :: (a,b) -> b
1457 snd (x,y) = y
1458
1459 instance (Ord a, Ord b) => Ord (a, b) where
1460     compare (a0, b0) (a1, b1) = compare a0 a1 &<& compare b0 b1
1461
1462 instance (Additive a, Additive b) => Additive (a, b) where
1463     zero = (zero, zero)
1464     (a0, b0) + (a1, b1) = (a0+a1, b0+b1)
1465
1466 instance Functor ((,) a) where
1467     fmap f (a,b) = (a, f b)
1468     
1469 instance (Show a, Show b) => Show (a, b) where
1470     sb <+ (x, y) = sb << "(" <+ x << ", " <+ y << ")"
1471
1472 /// Tuple3 ///
1473
1474 instance (Ord a, Ord b, Ord c) => Ord (a, b, c) where
1475     compare (a0, b0, c0) (a1, b1, c1) = compare a0 a1 &<& compare b0 b1 &<& compare c0 c1
1476
1477 instance (Additive a, Additive b, Additive c) => Additive (a, b, c) where
1478     zero = (zero, zero, zero)
1479     (a0, b0, c0) + (a1, b1, c1) = (a0+a1, b0+b1, c0+c1)
1480
1481 instance Functor ((,,) a b) where
1482     fmap f (a,b,c) = (a, b, f c)
1483
1484 instance (Show a, Show b, Show c) => Show (a, b, c) where
1485     sb <+ (x, y, z) = sb << "(" <+ x << ", " <+ y << ", " <+ z << ")"
1486
1487 /// Tuple4 ///
1488
1489 instance (Ord a, Ord b, Ord c, Ord d) => Ord (a, b, c, d) where
1490     compare (a0, b0, c0, d0) (a1, b1, c1, d1) = 
1491         compare a0 a1 &<& compare b0 b1 &<& compare c0 c1 &<& compare d0 d1
1492
1493 instance (Additive a, Additive b, Additive c, Additive d) => Additive (a, b, c, d) where
1494     zero = (zero, zero, zero, zero)
1495     (a0, b0, c0, d0) + (a1, b1, c1, d1) = (a0+a1, b0+b1, c0+c1, d0+d1)
1496
1497 instance Functor ((,,,) a b c) where
1498     fmap f (a,b,c,d) = (a, b, c, f d)
1499
1500 instance (Show a, Show b, Show c, Show d) => Show (a, b, c, d) where
1501     sb <+ (x, y, z, w) = sb << "(" <+ x << ", " <+ y << ", " <+ z << ", " <+ w << ")"
1502     
1503 /// Tuple5 ///
1504
1505 instance (Ord a, Ord b, Ord c, Ord d, Ord e) => Ord (a, b, c, d, e) where
1506     compare (a0, b0, c0, d0, e0) (a1, b1, c1, d1, e1) = 
1507         compare a0 a1 &<& compare b0 b1 &<& compare c0 c1 &<& compare d0 d1 &<& compare e0 e1
1508     
1509 instance (Additive a, Additive b, Additive c, Additive d, Additive e) => Additive (a, b, c, d, e) where
1510     zero = (zero, zero, zero, zero, zero)
1511     (a0, b0, c0, d0, e0) + (a1, b1, c1, d1, e1) = (a0+a1, b0+b1, c0+c1, d0+d1, e0+e1)
1512
1513 instance Functor ((,,,,) a b c d) where
1514     fmap f (a,b,c,d,e) = (a, b, c, d, f e)
1515
1516 /// Lists ///
1517
1518 instance (Ord a) => Ord [a] where
1519     compare a b = loop 0 
1520       where
1521         lA = length a
1522         lB = length b
1523         loop i = if i >= lA
1524                  then (if i >= lB then 0 else -1)
1525                  else if i >= lB
1526                  then 1
1527                  else compare (a!i) (b!i) &<& loop (i+1)
1528
1529 instance Functor [] where
1530     fmap = mapList
1531
1532 instance FunctorE [] where
1533     map = mapEList
1534     iter = iterList
1535     iterI = iterIList
1536         
1537 instance Monad [] where
1538     return x = singletonList x
1539     l >>= f  = concatMap f l
1540     join l   = l >>= id
1541
1542 instance MonadZero [] where
1543     mzero = emptyList
1544
1545 instance MonadPlus [] where
1546     mplus = appendList
1547
1548 instance Additive [a] where
1549     zero = emptyList
1550     (+) = appendList
1551
1552 instance FunctorM [] where
1553     sequence = foldl (\m mel -> m >>= \l -> mel >>= \el -> return (addList l el)) (return emptyList)
1554     mapM f l = sequence (map f l)
1555
1556 "Appends the string representations of all elements of the list to the string builder and separates the values with the given separator."
1557 printWithSeparator :: Show a => StringBuilder.T -> String -> [a] -> <Proc> StringBuilder.T
1558 printWithSeparator sb sep l = loop 0
1559   where
1560     len = length l
1561     loop i = if i >= len then sb
1562              else do
1563                  (if i==0 then sb else sb << sep) <+ l!i
1564                  loop (i+1)
1565
1566 """
1567 Joins the string representations of the list of values with the given separator.
1568
1569 See [intercalate](#intercalate) for an alternative that works with Strings
1570 and doesn't escape its arguments.
1571 """
1572 joinWithSeparator :: Show a => String -> [a] -> String
1573 joinWithSeparator separator values = runProc ( 
1574     StringBuilder.toString $ printWithSeparator StringBuilder.new separator values)
1575
1576
1577 """
1578 The intercalate function takes a String and a list of Strings
1579 and concatenates the list after interspersing the first argument
1580 between each element of the list.
1581
1582 See also more generic [joinWithSeparator](#joinWithSeparator)
1583 which escapes its arguments using `show`.
1584 """
1585 intercalate :: String -> [String] -> String
1586 intercalate separator strings = do
1587     l = length strings
1588     if l == 0
1589     then ""
1590     else if l == 1
1591     then strings!0
1592     else runProc do
1593         sb = StringBuilder.new
1594         sb << strings!0
1595         loop i | i == l = ()
1596                | otherwise = do
1597             sb << separator << strings!i
1598             loop (i+1)
1599         loop 1
1600         StringBuilder.toString sb
1601
1602 instance (Show a) => Show [a] where
1603     sb <+ l = do 
1604         len = length l
1605         loop i = if i < len 
1606                  then do 
1607                      if (i>0) then sb << ", " else sb
1608                      sb <+ l!i
1609                      loop (i+1)
1610                  else sb << "]"
1611         sb << "[" 
1612         loop 0                 
1613
1614 importJava "java.util.List" where
1615     "`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."
1616     @JavaName get
1617     getList :: [a] -> Integer -> a
1618
1619     @private
1620     @JavaName size
1621     lengthList :: [a] -> Integer
1622
1623     @private
1624     subList :: [a] -> Integer -> Integer -> [a]
1625
1626     @private
1627     isEmpty :: [a] -> Boolean
1628     
1629 @private    
1630 importJava "java.util.Collections" where
1631     emptyList :: [a]
1632     //singletonList :: a -> [a]
1633
1634 /*
1635 @inline
1636 emptyList :: [a]
1637 emptyList = build (\empty cons -> empty)
1638 */
1639
1640 "Creates a list with exectly one element."
1641 @inline
1642 singletonList :: a -> [a]
1643 singletonList v = build (\empty cons -> cons empty v)
1644
1645 /*
1646 // foldl f i (a + b) = foldl f (foldl f i a) b 
1647
1648 appendList :: [a] -> [a] -> [a]
1649 appendList a b = build (\empty cons -> foldl cons (foldl cons empty a) b)
1650 */
1651
1652 importJava "org.simantics.scl.runtime.list.ShareableList" where
1653     "Concatenates two lists."
1654     @private
1655     @JavaName "concat"
1656     appendList :: [a] -> [a] -> [a]
1657     
1658     "Adds the given value to the end of the list."
1659     @JavaName "add"   
1660     addList :: [a] -> a -> [a]
1661
1662 @private
1663 importJava "java.util.ArrayList" where
1664     data ArrayList a
1665
1666     @JavaName "<init>"
1667     newArrayList :: <Proc> ArrayList a
1668     
1669     @JavaName add
1670     addArrayList :: ArrayList a -> a -> <Proc> ()
1671
1672 """
1673 A primitive for constructing a list by `empty` and `cons` operations given to the function given as a parameter to this function.
1674 For example:
1675
1676     build (\empty cons -> cons (cons (cons empty 1) 2) 3)
1677     
1678 produces
1679
1680     [1, 2, 3]
1681     
1682 The SCL compiler makes the following optimization when encountering `build` and `foldl` functions after inlining:
1683
1684     foldl f i (build g) = g i f
1685 """
1686 @inline 2
1687 build :: forall b e2. (forall a e1. a -> (a -> b -> <e1> a) -> <e1,e2> a) -> <e2> [b]
1688 build f = runProc do
1689     l = newArrayList
1690     f () (\_ v -> addArrayList l v)
1691     Java.unsafeCoerce l
1692
1693 "A specific implementation of `map` for lists."
1694 @private
1695 @inline
1696 mapEList :: (a -> <e> b) -> [a] -> <e> [b]
1697 mapEList f l = build (\empty cons -> foldl (\cur x -> cons cur (f x)) empty l) 
1698
1699 "A specific implementation of `fmap` for lists."
1700 @inline
1701 mapList :: (a -> b) -> [a] -> [b]
1702 mapList f l = build (\empty cons -> foldl (\cur x -> cons cur (f x)) empty l) 
1703  
1704 "`guardList v` returns a singleton `[()]` if `v=True` and the empty list if `v=False`."
1705 @inline
1706 guardList :: Boolean -> [()]
1707 guardList cond = build (\empty cons -> if cond then cons empty () else empty) 
1708
1709 """
1710 `concatMap` combines `map` and `join` functions.
1711 It maps the elements of a given list to lists with the given function and concatenates the results.
1712
1713     concatMap f lst = join (map f lst) = [y | x <- lst, y <- f x] 
1714 """
1715 @inline
1716 concatMap :: (a -> <e> [b]) -> [a] -> <e> [b]
1717 concatMap f l = build (\empty cons -> foldl (\cur le -> foldl cons cur (f le)) empty l)
1718
1719 """
1720 Applies the given function to the elements of the lists until the function returns something
1721 else than `Nothing`. This return value is also returned as a result of this function.
1722 """
1723 @inline
1724 mapFirst :: (a -> <e> Maybe b) -> [a] -> <e> Maybe b
1725 mapFirst f l = loop 0 
1726   where
1727     len = length l
1728     loop i = if i == len
1729              then Nothing
1730              else match f (l!i) with
1731                  r @ (Just _) -> r
1732                  Nothing -> loop (i+1)
1733
1734 """
1735     foldl op initialValue list
1736     
1737 applies a binary operator `op` to all elements of `list` from left to right
1738 starting with `initialValue`. For example, 
1739
1740     foldl op init [x1, x2, x3, x4] = (((init `op` x1) `op` x2) `op` x3) `op` x4
1741 """
1742 @inline 2
1743 foldl :: forall a b e. (a -> b -> <e> a) -> a -> [b] -> <e> a
1744 foldl f initial l = loop initial 0
1745   where
1746     len = length l
1747     loop cur i = if i==len
1748                  then cur
1749                  else loop (f cur (l!i)) (i+1)
1750
1751 foldlI :: forall a b e. (Integer -> a -> b -> <e> a) -> a -> [b] -> <e> a
1752 foldlI f initial l = loop initial 0
1753   where
1754     len = length l
1755     loop cur i = if i==len
1756                  then cur
1757                  else loop (f i cur (l!i)) (i+1)
1758
1759 scanl :: (b -> a -> <e> b) -> b -> [a] -> <e> [b]
1760 scanl f initial l = build (\empty cons -> let
1761     len = length l
1762     loop cur i accum = let nl = cons accum cur
1763                            in if i==len
1764                            then nl
1765                             else loop (f cur (l!i)) (i+1) nl
1766   in loop initial 0 empty)
1767   
1768 "`foldr` is defined like `foldl` but it process the list from right to left."
1769 @inline
1770 foldr :: (b -> a -> <e> a) -> a -> [b] -> <e> a
1771 foldr f initial l = loop initial (length l - 1)
1772   where
1773     loop cur i = if i < 0
1774                  then cur
1775                  else loop (f (l!i) cur) (i-1)
1776
1777 foldr1 :: (a -> a -> <e> a) -> [a] -> <e> a
1778 foldr1 f l = loop (l!(len-1)) (len-2)
1779   where
1780     len = length l
1781     loop cur i = if i < 0
1782                  then cur
1783                  else loop (f (l!i) cur) (i-1)
1784
1785 """
1786 `filter pred lst` returns those elements of `lst` that the predicate `pred` accepts. For example
1787
1788     filter (> 3) [1, 2, 3, 4, 5, 6] = [4, 5, 6]
1789 """ 
1790 @inline
1791 filter :: (a -> <e> Boolean) -> [a] -> <e> [a]
1792 filter p l = build (\empty cons -> foldl (\cur x -> if p x then cons cur x else cur) empty l)
1793
1794 """
1795 Takes those elements of the input list that match `(Just x)` and adds the contents to the resulting list. For example,
1796
1797     filterJust [Just 1, Nothing, Just 5] = [1, 5] 
1798 """
1799 @inline
1800 filterJust :: [Maybe a] -> [a]
1801 filterJust l = build (\empty cons -> foldl (\cur x -> match x with Just v -> cons cur v ; _ -> cur) empty l)
1802
1803 listToMaybe :: [a] -> Maybe a
1804 listToMaybe l = if isEmpty l then Nothing else Just (l!0)
1805
1806 maybeToList :: Maybe a -> [a]
1807 maybeToList (Just a) = [a]
1808 maybeToList _ = [] 
1809
1810 """
1811 `takeWhile p l`, returns the longest prefix (possibly empty) of list `l` of elements that satisfy `p`
1812 """
1813 takeWhile :: (a -> <e> Boolean) -> [a] -> <e> [a]
1814 takeWhile f l = loop 0 
1815   where
1816     len = length l
1817     loop i | i == len  = l
1818            | f (l!i)   = loop (i+1)
1819            | otherwise = take i l
1820
1821 partition :: (a -> <e> Boolean) -> [a] -> <e> ([a], [a])
1822 partition p l = runProc do
1823     res1 = newArrayList
1824     res2 = newArrayList
1825     for l (\el ->
1826         if p el
1827         then addArrayList res1 el
1828         else addArrayList res2 el
1829     )
1830     (Java.unsafeCoerce res1, Java.unsafeCoerce res2)
1831
1832 """
1833 `range begin end` produces a list of consecutive integers starting from `begin` and ending to `end` (including `end`).
1834 The compiler supports syntactic sugar `[begin..end]` for this function.
1835 """
1836 @inline    
1837 range :: Integer -> Integer -> [Integer]
1838 range first last = build (\empty cons -> do
1839     loop i cur = if i > last then cur else loop (i+1) (cons cur i)
1840     loop first empty)
1841
1842 "A specific implementation of `iter` for lists."
1843 @inline
1844 iterList :: (a -> <e> b) -> [a] -> <e> ()
1845 iterList f l = foldl (\_ x -> ignore (f x)) () l
1846
1847 "A specific implementation of `iterI` for lists."
1848 @inline
1849 iterIList :: (Integer -> a -> <e> b) -> [a] -> <e> ()
1850 iterIList f l = do foldl (\i x -> do f i x ; i+1) 0 l ; () 
1851
1852 """
1853 Generates a list from a given starting state and iteration function.
1854 For example
1855
1856     let nextState 0 = Nothing
1857         nextState i = Just (i, i `div` 2)
1858     in  unfoldr nextState 30
1859         
1860 produces
1861
1862     [30, 15, 7, 3, 1]
1863 """
1864 @inline
1865 unfoldr :: (b -> <e> Maybe (a, b)) -> b -> <e> [a]
1866 unfoldr f s = build (\empty cons -> do
1867     loop s cur =
1868         match f s with
1869             Just (el,newS) -> loop newS (cons cur el)
1870             _ -> cur
1871     loop s empty)
1872
1873 importJava "org.simantics.scl.runtime.Lists" where
1874     /*
1875     @private
1876     @JavaName map
1877     mapList :: (a -> b) -> [a] -> [b]    
1878     @private
1879     @JavaName map
1880     mapEList :: (a -> <e> b) -> [a] -> <e> [b]
1881     @private
1882     @JavaName iter
1883     iterList :: (a -> <e> ()) -> [a] -> <e> ()
1884     concatMap :: (a -> <e> [b]) -> [a] -> <e> [b]
1885     */ 
1886     """
1887     Combines two lists into one list of pairs. The length of the resulting list is the length of the smallest input list.
1888     
1889         zip [1, 2, 3, 4, 5] ['a', 'b', 'c'] = [(1, 'a'), (2, 'b'), (3, 'c')]
1890     """
1891     zip :: [a] -> [b] -> [(a,b)]
1892     "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."
1893     zipWith :: (a -> b -> <e> c) -> [a] -> [b] -> <e> [c]
1894     """
1895     Produces two lists from one list of pairs.
1896     
1897         unzip [(1, 'a'), (2, 'b'), (3, 'c')] = ([1, 2, 3], ['a', 'b', 'c'])
1898     """
1899     unzip :: [(a,b)] -> ([a],[b])
1900     
1901     //"@filter p l@ returns those elements of @l@ that the predicate @p@ accepts." 
1902     //filter :: (a -> <e> Boolean) -> [a] -> <e> [a]
1903     //filterJust :: [Maybe a] -> [a]
1904     /*
1905     foldl :: (a -> b -> <e> a) -> a -> [b] -> <e> a
1906     */
1907     "Like `foldl` but assumes that the list is non-empty so the initial is not needed."
1908     foldl1 :: (a -> a -> <e> a) -> [a] -> <e> a
1909     //unfoldr :: (b -> <e> Maybe (a, b)) -> b -> <e> [a]
1910     
1911     "Sorts the list using the given comparator."
1912     sortWith :: (a -> a -> <e> Integer) -> [a] -> <e> [a]
1913     "Works like `index` but uses the given functions as hash codes and equality."
1914     indexWith :: (a -> Integer) -> (a -> a -> Boolean) -> [(a,b)] -> a -> Maybe b
1915     groupWith :: (b -> Integer) -> (b -> b -> Boolean) -> (a -> <e> b) -> (a -> <e> c) -> [a] -> <e> [(b, [c])]
1916     "Works like `unique` but uses the given function for equality tests."
1917     uniqueWith :: (a -> a -> Boolean) -> [a] -> [a]
1918     "Works like `\\\\` but uses the given function for equality tests."
1919     deleteAllBy :: (a -> a -> Boolean) -> [a] -> [a] -> [a]
1920     
1921     //range :: Integer -> Integer -> [Integer]
1922     
1923     //build :: (forall a. a -> (a -> b -> <e> a) -> <e> a) -> <e> [b]
1924
1925 "`elem el lst` return true, if `el` occurs in the list `lst`."
1926 elem :: a -> [a] -> Boolean
1927 elem el l = loop 0
1928   where
1929     len = length l
1930     loop i | i < len = if el == l!i
1931                        then True
1932                        else loop (i+1)
1933            | otherwise = False
1934
1935 "`elemMaybe v1 (Just v2)` returns true if `v1 == v2`. `elemMaybe v1 Nothing` is always false."
1936 elemMaybe :: a -> Maybe a -> Boolean
1937 elemMaybe el m = match m with
1938     Just el2 -> el == el2
1939     Nothing -> False
1940
1941 """
1942 Computes a list that contains only elements that belongs to both input lists.
1943 """
1944 intersect :: [a] -> [a] -> [a]
1945 intersect a b = filter f a
1946   where
1947     f e = elem e b
1948
1949 "Reverses a given list. For example, `reverse [1,2,3] = [3,2,1]`"
1950 reverse :: [a] -> [a]
1951 reverse l = [l!(len-i) | i <- [1..len]]
1952   where
1953     len = length l
1954
1955 """
1956 Transposes the rows and columns of its argument. For example,
1957
1958     transpose [[1,2,3],[4,5,6]] == [[1,4],[2,5],[3,6]]
1959     transpose [[1,2],[3,4,5]] == [[1,3],[2,4],[5]]
1960 """
1961 transpose xss = [[xs!i | xs <- xss, i < length xs]
1962                 | i <- [0..maximum [length xs | xs <- xss]-1]]
1963
1964 "Works like `unfoldr` but generates the list from right to left."
1965 unfoldl :: (b -> <e> Maybe (a, b)) -> b -> <e> [a]
1966 unfoldl f seed = reverse $ unfoldr f seed
1967
1968 "Removes the first element of the list, if the list is non-empty."
1969 tail :: [a] -> [a]
1970 tail l = if len < 2 then emptyList else subList l 1 len 
1971   where 
1972     len = length l
1973
1974 "Tries to find the given key from the list of key-value pairs and returns the corresponding value."
1975 lookup ::  a -> [(a, b)] -> Maybe b
1976 lookup el l = do
1977     len = length l
1978     loop i = if i < len 
1979              then match l!i with
1980                (a,b) | a == el   -> Just b
1981                      | otherwise -> loop (i+1)
1982              else Nothing
1983     loop 0
1984
1985 "Conjunction over a list."
1986 @inline
1987 and :: [Boolean] -> Boolean
1988 and = foldl (&&) True
1989
1990 "Disjunction over a list."
1991 @inline
1992 or :: [Boolean] -> Boolean
1993 or  = foldl (||) False
1994
1995 """
1996 `any pred lst` tests whether the predicate `pred` holds some element of `lst`.
1997 It returns immediately when it encounters the first value satisfying the predicate.
1998 """ 
1999 any :: (a -> <e> Boolean) -> [a] -> <e> Boolean
2000 any p =  or . map p
2001
2002 """
2003 `all pred lst` tests whether the predicate `pred` holds for all elements of `lst`.
2004 It returns immediately when it encounters the first value not satisfying the predicate.
2005 """ 
2006 all :: (a -> <e> Boolean) -> [a] -> <e> Boolean
2007 all p =  and . map p
2008
2009 """
2010 Returns the first element of the list satisfying the given condition,
2011 or `Nothing` if there is no such element.
2012 """
2013 findFirst :: (a -> <e> Boolean) -> [a] -> <e> Maybe a
2014 findFirst p l = loop 0
2015   where
2016     len = length l
2017     loop i = if i < len 
2018              then let el = l!i in 
2019                   if p el 
2020                   then Just el 
2021                   else loop (i+1)
2022              else Nothing
2023     loop 0
2024
2025
2026 """
2027 Sorts the given list using its default order.
2028 """
2029 @inline
2030 sort :: Ord a => [a] -> [a]
2031 sort = sortWith compare
2032
2033 """
2034 Sorts the lists by the values computed by the first function.
2035 For example
2036
2037     sortBy snd [(1,5), (2,3), (3,4)] = [(2,3), (3,4), (1,5)] 
2038 """
2039 @inline
2040 sortBy :: Ord b => (a -> <e> b) -> [a] -> <e> [a]
2041 sortBy f l = sortWith (\x y -> compare (f x) (f y)) l
2042 // This is faster if f is slow, but will generate more auxiliary structures
2043 //sortBy f l = map snd (sortWith (\(x,_) (y,_) -> compare x y) [(f x, x) | x <- l])
2044
2045 """
2046 Given a list of key-value pairs, the function produces a function that finds a value
2047 efficiently for the given key.
2048 """
2049 index :: [(a,b)] -> a -> Maybe b
2050 index = indexWith hashCode (==)
2051
2052 """
2053 Given a list of values and a function computing a key for each value, the function produces a function that finds a value
2054 effeciently for the given key.
2055 """
2056 indexBy ::  (a -> b) -> [a] -> b -> Maybe a
2057 indexBy f l = index [(f x, x) | x <- l]
2058
2059 "Groups a list values by a key computed by the given function."
2060 groupBy :: (a -> <e> b) -> [a] -> <e> [(b, [a])]
2061 groupBy f l = groupWith hashCode (==) f id l
2062
2063 "Groups a list of key-value pairs by the keys."
2064 group :: [(a,b)] -> [(a, [b])]
2065 group = groupWith hashCode (==) fst snd
2066
2067 "Removes duplicates (all but the first occurrence) from the list but otherwise preserves the order of the elements."
2068 unique ::  [a] -> [a]
2069 unique = uniqueWith (==)
2070
2071 "Like `unique`, but uses the given function for finding the key values used for uniqueness testing."
2072 uniqueBy :: (a -> b) -> [a] -> [a]
2073 uniqueBy f = uniqueWith (\a b -> f a == f b)
2074
2075 //sortAndUniqueBy :: Ord b => (a -> b) -> [a] -> [a]
2076 //sortAndUniqueBy f = map snd . uniqueWith (\a b -> fst a == fst b) . sortBy fst . map (\x -> (f x, x))
2077
2078 "`a \\\\ b` removes all elements of `b` from the list `a`."
2079 (\\) :: [a] -> [a] -> [a]
2080 (\\) = deleteAllBy (==)
2081
2082 /// Dynamic ///
2083
2084 importJava "java.lang.Object" where
2085     "A data type that can represent any value."
2086     data Dynamic
2087     
2088     @private
2089     @JavaName toString
2090     showDynamic :: Dynamic -> String
2091
2092 instance Show Dynamic where
2093     show = showDynamic
2094
2095 "Converts a value to `Dynamic` type."
2096 toDynamic :: a -> Dynamic
2097 toDynamic = Java.unsafeCoerce
2098
2099 "Converts a `Dynamic` value to a required value, or fails if the conversion is not possible."
2100 importJava "org.simantics.scl.compiler.runtime.ValueConversion" where
2101     fromDynamic :: Typeable a => Dynamic -> a
2102
2103 /// Procedures ///
2104
2105 importJava "org.simantics.scl.runtime.procedure.Ref" where
2106     "A mutable reference to a value of type `a`."
2107     data Ref a
2108     
2109     "Creates a new reference with the given initial value."
2110     @JavaName "<init>"
2111     ref :: a -> <Proc> (Ref a)
2112     
2113     "Returns the current value of the reference."
2114     @JavaName "value"
2115     getRef :: Ref a -> <Proc> a
2116     
2117     "Sets a new value for the reference."
2118     @JavaName "<set>value"
2119     (:=) :: Ref a -> a -> <Proc> ()
2120
2121 instance Show (Ref a) where
2122     show _ = "<reference>"
2123
2124 importJava "org.simantics.scl.runtime.reporting.SCLReporting" where
2125     "Prints the given string to the console."
2126     @JavaName "print"
2127     printString :: String -> <Proc> ()
2128     "Prints an error message to the console."
2129     printError :: String -> <Proc> ()
2130     "Reports that certain amount of work has been done for the current task."
2131     didWork :: Double -> <Proc> ()
2132     """
2133     `printingToFile "fileName" expression` executes the `expression` so that all its console prints
2134     are written to the file given as a first parameter.
2135     """
2136     printingToFile :: String -> (<e> a) -> <e> a
2137     """
2138     `printErrorsAsNormalPrints expression` executes the `expression` so that all its error prints
2139     are printed as normal prints. This is useful mainly in testing scripts for checking that the implementations
2140     give proper error messages with invalid inputs.
2141     """
2142     printErrorsAsNormalPrints :: (<e> a) -> <e> a
2143     """
2144     `disablePrintingForCommand expression` executes the `expression` so that it does not print return values.
2145     Errors are printed normally.
2146     """
2147     disablePrintingForCommand :: (<e> a) -> <e> a
2148     
2149
2150 importJava "org.simantics.scl.runtime.procedure.Procedures" where
2151     "Returns `True` if the current thread has been interrupted."
2152     isInterrupted :: <Proc> Boolean
2153     "Checks whether the current thread has been interrupted and throws an exception if it is."
2154     checkInterrupted :: <Proc> ()
2155     "Generates a random identifier."
2156     generateUID :: <Proc> String
2157     
2158     "Executes the given expression and catches certain class of exceptions (specified by the catch handler that is given as a second parameter.)"
2159     @JavaName catch_
2160     catch :: VecComp ex => (<e,Exception> a) -> (ex -> <e> a) -> <e> a
2161
2162 importJava "java.lang.Throwable" where
2163     data Throwable
2164     @private
2165     @JavaName toString
2166     showThrowable :: Throwable -> String
2167 importJava "java.lang.Exception" where
2168     data Exception
2169     @private
2170     @JavaName toString
2171     showException :: Exception -> String
2172
2173 instance Show Throwable where
2174     show = showThrowable
2175 instance Show Exception where
2176     show = showException
2177
2178 "Prints the given value in the console."
2179 @inline
2180 print :: Show a => a -> <Proc> ()
2181 print v = printString (showForPrinting v)
2182 /*
2183 instance Show TypeRep where
2184     sb <+ (TApply (TCon "Builtin" "[]") b) = 
2185         sb << "[" <+ b << "]"
2186     sb <+ (TApply (TApply (TCon "Builtin" "(,)") c1) c2) = 
2187         sb << "(" <+ c1 << "," <+ c2 << ")"
2188     sb <+ (TApply (TApply (TApply (TCon "Builtin" "(,,)") c1) c2) c3) = 
2189         sb << "(" <+ c1 << "," <+ c2 << "," <+ c3 << ")"
2190     sb <+ (TApply (TApply (TApply (TApply (TCon "Builtin" "(,,,)") c1) c2) c3) c4) =
2191         sb << "(" <+ c1 << "," <+ c2 << "," <+ c3 << "," <+ c4 << ")" 
2192     
2193     sb <+ (TCon _ name) = sb << name
2194     sb <+ (TApply a b) = sb <+ Par 1 a << " " <+ Par 2 b
2195     sb <+ (TFun a b) = sb <+ Par 1 a << " -> " <+ b
2196     
2197     precedence (TCon _ _) = 0
2198     precedence (TFun _ _) = 2
2199     precedence (TApply a _) = if isSpecialType a then 0 else 1
2200       where
2201         isSpecialType (TCon "Builtin" "[]") = True
2202         isSpecialType (TCon "Builtin" "()") = True
2203         isSpecialType (TCon "Builtin" "(,)") = True
2204         isSpecialType (TCon "Builtin" "(,,)") = True
2205         isSpecialType (TCon "Builtin" "(,,,)") = True
2206         isSpecialType (TApply a _) = isSpecialType a
2207 */
2208
2209 // ByteArray
2210
2211 importJava "java.util.Arrays" where
2212     @private
2213     @JavaName toString
2214     byteArrayToString :: ByteArray -> String
2215
2216 instance Show ByteArray where
2217     show = byteArrayToString
2218
2219 // Type
2220
2221 @private
2222 importJava "org.simantics.scl.compiler.types.Type" where
2223     @JavaName toString
2224     showType :: Type -> String
2225
2226 importJava "org.simantics.scl.compiler.types.Types" where
2227     removeForAll :: Type -> Type
2228     
2229 instance Show Type where
2230     show = showType