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