1 import "JavaBuiltin" as Java
2 import "StringBuilder" as StringBuilder
4 /** The following types and names are builtin *************
5 data Boolean = True | False
24 data [a] = [] | [a] | [a,a] | [a,a,a] | ...
27 data (a,b,c) = (a,b,c)
28 data Maybe a = Nothing | Just a
32 data TypeRep = TCon String | TApply TypeRep TypeRep
34 typeOf :: Typeable a => a -> Type
38 binding :: Serializable a => Binding a
39 ***********************************************************/
41 importJava "java.util.Arrays" where
44 equalsDoubleArray :: DoubleArray -> DoubleArray -> Boolean
48 showDoubleArray :: DoubleArray -> String
50 "Converts an array to a list."
52 arrayToList :: Array a -> [a]
54 importJava "java.util.List" where
55 "Converts a list to an array."
57 listToArray :: [a] -> Array a
59 instance Eq DoubleArray where
60 (==) = equalsDoubleArray
61 instance Show DoubleArray where
62 show = showDoubleArray
64 importJava "org.simantics.scl.runtime.Coercion" where
65 "Converts a list of doubles to a double array."
66 toDoubleArray :: [Double] -> DoubleArray
67 "Converts a double array to a list of doubles."
68 fromDoubleArray :: DoubleArray -> [Double]
71 * Precedences and associativity of all operators defined in Prelude
77 infixl 7 (*), (/), div, mod
79 infixl 5 (\\), (<<), (<+)
80 infix 4 (==), (!=), (<), (<=), (>=), (>)
82 infixr 2 (||), orElse, morelse
83 infixr 1 (>>=), (>>), (:=)
87 "Creates a constant function. `const x` defines a function that always returns `x`."
93 Function application. `f $ x` is equivalent with `f x`. The function has two uses.
94 First is to remove parentheses from deeply nested expressions:
96 f (g (h x)) == f $ g $ h x
98 The second use is with higher order functions:
100 map ($ parameter) functions
104 ($) :: (a -> <e> b) -> a -> <e> b
107 "Transforms a function taking a pair as a parameter to a function taking two values as a parameter."
109 curry :: ((a, b) -> <e> c) -> a -> b -> <e> c
110 curry f x y = f (x, y)
112 "Transforms a function two values as a parameter to a function taking a pair as a parameter."
114 uncurry :: (a -> b -> <e> c) -> ((a, b) -> <e> c)
115 uncurry f (x, y) = f x y
117 "Transforms a function taking a triple as a parameter to a function taking three values as a parameter."
119 curry3 :: ((a, b, c) -> <e> d) -> a -> b -> c -> <e> d
120 curry3 f x y z = f (x, y, z)
122 "Transforms a function three values as a parameter to a function taking a priple as a parameter."
124 uncurry3 :: (a -> b -> c -> <e> d) -> ((a, b, c) -> <e> d)
125 uncurry3 f (x, y, z) = f x y z
127 "Flips the parameters of a binary function."
129 flip :: (a -> b -> <e> c) -> b -> a -> <e> c
132 swap :: (a,b) -> (b,a)
138 The class of types whose elements can be compared for equality.
139 Method `(==)` must be implemented in instances.
143 (==) :: a -> a -> Boolean
144 "Inequality: `a != b = not (a == b)`"
145 (!=) :: a -> a -> Boolean
147 a != b = not (a == b)
150 The class of linearly ordered types.
151 Method `compare` must be implemented in instances.
153 class (Eq a) => Ord a where
155 `compare x y` returns a negative number, if `x` is smaller than `y`,
156 a positive number, if `x` is bigger than `y` and zero if they are equal.
158 compare :: a -> a -> Integer
159 compare a b = if a < b then -1 else if a > b then 1 else 0
162 (<) :: a -> a -> Boolean
163 a < b = compare a b < 0
165 (<=) :: a -> a -> Boolean
166 a <= b = compare a b <= 0
168 (>) :: a -> a -> Boolean
169 a > b = compare a b > 0
171 (>=) :: a -> a -> Boolean
172 a >= b = compare a b >= 0
174 "Minimum of the parameters"
176 min a b = if a < b then a else b
177 "Maximum of the parameters"
179 max a b = if a > b then a else b
182 Combines two integers such that if the first one is non-zero, it is returned, otherwise
183 the second-one. The second parameter is not implemented, if it is not needed.
185 The function is useful for implementing efficient recursive comparison of structures,
188 compare (x1,y1,z1) (x2,y2,z2) = compare x1 x2 &<& compare y1 y2 &<& compare z1 z2
191 (&<&) :: Integer -> (<e> Integer) -> <e> Integer
192 a &<& b = if a == 0 then b else a
194 "Maximum over a list"
196 maximum :: Ord a => [a] -> a
199 "Minimum over a list"
201 minimum :: Ord a => [a] -> a
204 "As `maximum` but compares the elements by the given projection."
205 maximumBy :: Ord b => (a -> <e> b) -> [a] -> <e> a
206 maximumBy f l = snd $ foldl1 maxF $ map (\x -> (f x, x)) l
208 maxF a b = if fst a >= fst b then a else b
211 As `minimum` but compares the elements by the given projection.
216 returns a pair with the smallest second component.
218 minimumBy :: Ord b => (a -> <e> b) -> [a] -> <e> a
219 minimumBy f l = snd $ foldl1 minF $ map (\x -> (f x, x)) l
221 minF a b = if fst a <= fst b then a else b
224 The class of types with method to compute hash codes.
226 class (Eq a) => Hashable a where
227 "`hashP v seed` computes the hash code of `v` using `seed` as a seed."
228 hashP :: a -> Integer -> Integer
230 "`hash v` computes the hash code of `v`"
231 hash :: Hashable a => a -> Integer
232 hash a = hashP a 1166136261
236 instance Functor ((->) a) where
239 instance Monad ((->) a) where
241 (m >>= f) x = f (m x) x
244 instance Category (->) where
249 instance (Additive b) => Additive (a -> <e> b) where
251 (f + g) x = f x + g x
253 instance (Ring b) => Ring (a -> <e> b) where
255 (neg f) x = neg (f x)
256 (f - g) x = f x - g x
257 (f * g) x = f x * g x
258 (fromInteger c) x = fromInteger c
260 //instance Show (a -> <e> b) where
261 // show f = "<function>"
263 "Appends a string to the string builder."
264 (<<) :: StringBuilder.T -> String -> <Proc> StringBuilder.T
265 (<<) = StringBuilder.appendString
268 The class of types whose elements can be converted to a string representation.
269 Method `show` or `(<+)` must be implemented.
272 "Converts a value to string."
274 "Appends the string representation of the value to the string builder."
275 (<+) :: StringBuilder.T -> a -> <Proc> StringBuilder.T
277 Returns the precedence of the value. It is used to determine if parenteheses
278 are needed around the string representation of the value. The default value is 0
279 and means that parentheses are never added.
281 precedence :: a -> Integer
283 "Converts a value to a string like `show` but does not put string literals in double quotes."
284 showForPrinting :: a -> String
286 show v = runProc (StringBuilder.toString (StringBuilder.new <+ v))
287 showForPrinting v = show v
288 sb <+ v = StringBuilder.appendString sb (show v)
292 `Par` data type is used to control the placement of parentheses when converting values to string.
293 Value `Par prec val` is converted to string like `val` but parentheses are put around, if the
294 precedence of the value is greater than `prec`.
296 data Par a = Par Integer a
298 instance (Show a) => Show (Par a) where
299 sb <+ (Par outerPrec v) = if prec > outerPrec
300 then sb << "(" <+ v << ")"
302 where prec = precedence v
304 "Type class for parsing strings to values."
306 "Converts a string to a required type of value."
309 The `Additive` class is used for types that are additive monoids. The operations
310 must satisfy the following laws (at least approximately, when implemented for
311 floating point numbers):
312 (a + b) + c = a + (b + c)
315 class Additive a where
317 Neutral element of (+), i.e,
323 "Adds two objects (numbers, vectors, strings, etc.) together."
328 sum [e1,e2,...,eN] = e1 + e2 + ... + eN
330 Implemented usually more efficiently than with repetitive
331 application of `(+)`.
336 class (Additive a) => AdditiveGroup a where
342 The `Ring` class is used for types that are algebraic rings. The operations
343 must satisfy the following laws (at least approximately)
344 in addition to the laws of Additive:
349 (a * b) * c = a * (b * c)
351 a * (b + c) = a * b + a * c
352 (a + b) * c = a * c + b * c
354 class (Additive a) => Ring a where
356 Negation. Synonym for unary `-`.
361 "Neutral element of multiplication"
365 "Converts an integer to a desired numeric type."
366 fromInteger :: Integer -> a
371 The `OrderedRing` class combines the Ring and Ord classes. It additionally
372 supports absolute value function.
374 class (Ring a, Ord a) => OrderedRing a where
377 abs x = if x < zero then neg x else x
378 "Converts the given number to `Integer`"
379 toInteger :: a -> Integer
382 The `Integer` class is used for types that represent either all integers or some
385 class (OrderedRing a) => Integral a where
386 "Integer division truncated toward zero."
388 "Integer remainder, satisfying ``(x `div` y)*y + (x `mod` y) = x``"
392 The `Real` class is used for types that represent some approximation of real numbers.
394 class (OrderedRing a) => Real a where
399 "Pi (3.141592654...)"
425 "Inverse hyberbolic sine"
427 "Inverse hyberbolic cosine"
429 "Inverse hyberbolic tangent"
431 "The largest integer not greater than the given number"
433 "The smallest integer not smaller than the given number"
437 Two parameter version of `atan`. Its value is determined by the following
438 equations when (x,y) is a unit vector:
445 atan2 y x = atan (y/x)
448 "Converts a `Double` value to a desired numeric type."
449 fromDouble :: Double -> a
450 "Converts the given number to `Double`"
451 toDouble :: a -> Double
453 a ^ b = exp (b * log a)
455 sinh x = 0.5 * (exp x - exp (neg x))
456 cosh x = 0.5 * (exp x + exp (neg x))
457 tanh x = (e2x - 1) / (e2x + 1)
461 asinh x = log (x + sqrt (x*x + one))
462 acosh x = log (x + sqrt (x*x - one))
463 atanh x = 0.5 * log ((one+x)/(one-x))
465 /// Import mathematical functions ///
468 importJava "java.lang.Math" where
473 sinDouble :: Double -> Double
476 cosDouble :: Double -> Double
479 tanDouble :: Double -> Double
482 asinDouble :: Double -> Double
485 acosDouble :: Double -> Double
488 atanDouble :: Double -> Double
491 atan2Double :: Double -> Double -> Double
494 sinhDouble :: Double -> Double
497 coshDouble :: Double -> Double
500 tanhDouble :: Double -> Double
503 expDouble :: Double -> Double
506 logDouble :: Double -> Double
509 powDouble :: Double -> Double -> Double
512 sqrtDouble :: Double -> Double
515 ceilDouble :: Double -> Double
518 floorDouble :: Double -> Double
521 roundDouble :: Double -> Long
524 absInteger :: Integer -> Integer
527 absLong :: Long -> Long
530 absFloat :: Float -> Float
533 absDouble :: Double -> Double
536 minInteger :: Integer -> Integer -> Integer
539 minLong :: Long -> Long -> Long
542 minFloat :: Float -> Float -> Float
545 minDouble :: Double -> Double -> Double
548 maxInteger :: Integer -> Integer -> Integer
551 maxLong :: Long -> Long -> Long
554 maxFloat :: Float -> Float -> Float
557 maxDouble :: Double -> Double -> Double
562 importJava "java.lang.Byte" where
564 showByte :: Byte -> String
567 readByte :: String -> Byte
569 instance Eq Byte where
573 instance Ord Byte where
579 instance Additive Byte where
580 zero = Java.i2b Java.iconst_0
583 instance Ring Byte where
586 one = Java.i2b Java.iconst_1
588 fromInteger = Java.i2b
590 instance Show Byte where
592 precedence v = if v >= 0 then 0 else 100
594 instance Read Byte where
599 importJava "java.lang.Short" where
601 showShort :: Short -> String
604 readShort :: String -> Short
606 instance Eq Short where
610 instance Ord Short where
616 instance Additive Short where
620 instance Ring Short where
625 fromInteger = Java.i2s
627 instance Show Short where
629 precedence v = if v >= 0 then 0 else 100
631 instance Read Short where
637 importJava "java.lang.Integer" where
639 showInteger :: Integer -> String
642 readInteger :: String -> Integer
644 instance Eq Integer where
648 instance Ord Integer where
654 instance Hashable Integer where
655 hashP v x = Java.ixor v (Java.imul x 16777619) // prime for FNV-1 hash
657 instance Additive Integer where
661 instance Ring Integer where
668 instance OrderedRing Integer where
672 instance Integral Integer where
676 instance Show Integer where
678 precedence v = if v >= 0 then 0 else 100
680 instance Read Integer where
686 importJava "java.lang.Long" where
688 showLong :: Long -> String
691 readLong :: String -> Long
693 instance Eq Long where
697 instance Ord Long where
703 instance Hashable Long where
704 hashP v x = Java.l2i (Java.lxor v (Java.lushr v 32)) + x*16777619
706 instance Additive Long where
710 instance Ring Long where
715 fromInteger = Java.i2l
717 instance OrderedRing Long where
721 instance Integral Long where
725 instance Show Long where
727 precedence v = if v >= 0 then 0 else 100
729 instance Read Long where
734 importJava "java.lang.Float" where
737 compareFloat :: Float -> Float -> Integer
741 showFloat :: Float -> String
745 readFloat :: String -> Float
747 "Converts 32-bit floating point number to a 32-bit integer with the same byte level representation."
748 floatToIntBits :: Float -> Integer
750 instance Eq Float where
754 instance Ord Float where
755 compare = compareFloat
761 instance Hashable Float where
762 hashP v x = hashP (floatToIntBits v) x
764 instance Additive Float where
768 instance Ring Float where
773 fromInteger = Java.i2f
775 instance OrderedRing Float where
779 instance Real Float where
781 x ^ y = Java.d2f (powDouble (Java.f2d x) (Java.f2d y))
782 pi = fromDouble piDouble
783 sqrt = Java.d2f . sqrtDouble . Java.f2d
784 exp = Java.d2f . expDouble . Java.f2d
785 log = Java.d2f . logDouble . Java.f2d
786 sin = Java.d2f . sinDouble . Java.f2d
787 cos = Java.d2f . cosDouble . Java.f2d
788 tan = Java.d2f . tanDouble . Java.f2d
789 asin = Java.d2f . asinDouble . Java.f2d
790 acos = Java.d2f . acosDouble . Java.f2d
791 atan = Java.d2f . atanDouble . Java.f2d
792 sinh = Java.d2f . sinhDouble . Java.f2d
793 cosh = Java.d2f . coshDouble . Java.f2d
794 tanh = Java.d2f . tanhDouble . Java.f2d
795 floor = Java.d2f . floorDouble . Java.f2d
796 ceil = Java.d2f . ceilDouble . Java.f2d
797 atan2 y x = Java.d2f (atan2Double (Java.f2d y) (Java.f2d x))
798 round = roundDouble . Java.f2d
799 fromDouble = Java.d2f
802 instance Show Float where
804 precedence v = if v >= 0 then 0 else 100
806 instance Read Float where
811 importJava "java.lang.Double" where
814 compareDouble :: Double -> Double -> Integer
818 showDouble :: Double -> String
821 @JavaName parseDouble
822 readDouble :: String -> Double
824 "Converts 64-bit floating point number to a 64-bit integer with the same byte level representation."
825 doubleToLongBits :: Double -> Long
827 isFinite :: Double -> Boolean
828 isNaN :: Double -> Boolean
829 isInfinite :: Double -> Boolean
831 instance Eq Double where
835 instance Ord Double where
836 compare = compareDouble
842 instance Hashable Double where
843 hashP v x = hashP (doubleToLongBits v) x
845 instance Additive Double where
849 instance Ring Double where
854 fromInteger = Java.i2d
856 instance OrderedRing Double where
860 instance Real Double where
883 instance Show Double where
885 precedence v = if v >= 0 then 0 else 100
887 instance Read Double where
892 importJava "java.lang.Character" where
894 showCharacter :: Character -> String
896 "Returns true, if the given character is a letter."
897 isLetter :: Character -> Boolean
899 "Returns true, if the given character is a digit."
900 isDigit :: Character -> Boolean
902 instance Eq Character where
906 instance Ord Character where
912 instance Show Character where
913 sb <+ c = sb << "'" << showCharacter c << "'"
915 "Adds a given integer to the character code."
916 addChar :: Character -> Integer -> Character
919 "Subtracts a given integer from the character code."
920 subChar :: Character -> Character -> Integer
926 The `Functor` class is used for types that can be mapped over. Instances of `Functor` should satisfy the following laws:
929 fmap (f . g) == fmap f . fmap g
931 class Functor f where
932 "Lifts a pure function to the given functor."
933 fmap :: (a -> b) -> f a -> f b
935 class CoFunctor f where
936 comap :: (a -> b) -> f b -> f a
940 class (Functor f) => Applicative f where
942 (<*>) :: f (a -> b) -> f a -> f b
943 (*>) :: f a -> f b -> f b
944 (<*) :: f a -> f b -> f a
946 u *> v = pure (const id) <*> u <*> v
947 u <* v = pure const <*> u <*> v
948 fmap f x = pure f <*> x
953 The `Monad` class defines the basic operations over a monad, a concept from a branch of mathematics known as category theory.
954 From the perspective of a SCL programmer, however, it is best to think of a monad as an abstract datatype of actions.
955 SCL's `mdo expressions provide a convenient syntax for writing monadic expressions.
957 Instances of `Monad` should satisfy the following laws:
959 return a >>= k == k a
961 m >>= (\x -> k x >>= h) == (m >>= k) >>= h
962 fmap f xs == xs >>= return . f
964 class (Functor m) => Monad m where
965 "Inject a value into the monadic type."
967 "Sequentially compose two actions, passing any value produced by the first as an argument to the second."
968 (>>=) :: m a -> (a -> m b) -> m b
970 The join function is the conventional monad join operator. It removes one level of monadic
973 For lists, `join` concatenates a list of lists:
975 join [[1,2], [3,4]] = [1, 2, 3, 4]
977 join :: m (m a) -> m a
981 Sequentially compose two actions, discarding any value produced by the first, like sequencing operators
982 (such as the semicolon) in imperative languages."
985 (>>) :: Monad m => m a -> m b -> m b
986 a >> b = a >>= (\_ -> b)
988 "While loop. `while cond body` executes the `body` while the `cond` is true."
990 while :: (<e> Boolean) -> (<e> a) -> <e> ()
991 while cond body = loop ()
992 where loop _ = if cond
993 then do body ; loop ()
997 Sequences the given monadic value infinitely:
999 repeatForever m = m >> m >> m >> ...
1001 repeatForever m = m >> repeatForever m
1003 replicateM :: Monad m => Integer -> m a -> m [a]
1004 replicateM count m = loop count emptyList
1006 loop count l | count <= 0 = return l
1009 loop (count-1) (addList l v)
1011 replicateM_ :: Monad m => Integer -> m a -> m ()
1012 replicateM_ count m | count <= 0 = return ()
1013 | otherwise = m >> replicateM_ (count-1) m
1018 A class of monads with zero element satisfying
1022 class (Monad m) => MonadZero m where
1025 "Injects a boolean test to a type beloning to `MonadZero`."
1026 guard :: MonadZero m => Boolean -> m ()
1027 guard True = return ()
1033 A class of monads with associative binary operator `mplus` satisfying the following laws:
1037 mplus (mplus a b) c = mplus a (mplus b c)
1038 mplus a b >>= k = mplus (a >>= k) (b >>= k)
1040 class (MonadZero m) => MonadPlus m where
1041 mplus :: m a -> m a -> m a
1046 A class of monads with associative binary operator `morelse` satisfying the following laws:
1050 morelse (morelse a b) c = morelse a (morelse b c)
1051 morelse (return a) b = return a
1053 class (MonadZero m) => MonadOr m where
1054 morelse :: m a -> m a -> m a
1059 A class of types that can be mapped over with effectful mapping functions.
1061 class (Functor f) => FunctorE f where
1063 Applies the function to all elements of the container and
1064 returns the similarly shaped container with the results:
1068 map f [e1, e2, ..., eN] = [f e1, f e2, ..., f eN]
1072 map (*2) [1..5] = [2, 4, 6, 8, 10]
1074 map :: (a -> <e> b) -> f a -> <e> (f b)
1075 "Calls the given function with all elements of the given container."
1076 iter :: (a -> <e> b) -> f a -> <e> ()
1077 "Calls the given function with all elements of the given container giving also the index of the element as a parameter."
1078 iterI :: (Integer -> a -> <e> b) -> f a -> <e> ()
1080 "Iterates the elements of the given collection. Same as `iter` but parameters flipped."
1081 for :: FunctorE f => f a -> (a -> <e> b) -> <e> ()
1085 "Iterates the elements of the given collection providing also the indices of the elements. Same as `iterI` but parameters flipped."
1086 forI :: FunctorE f => f a -> (Integer -> a -> <e> b) -> <e> ()
1088 forI l f = iterI f l
1090 "`forN n f` calls `f` for all integers `0`, ..., `n-1`"
1092 forN :: Integer -> (Integer -> <e> b) -> <e> ()
1096 then do f i ; loop (i+1)
1100 mapI :: (Integer -> a -> <e> b) -> [a] -> <e> [b]
1101 mapI f l = build (\empty cons -> let
1103 loop i accum = if i < len
1104 then loop (i+1) (cons accum (f i (l!i)))
1109 `mapMaybe` combines `map` and `filter` functions.
1110 It applies the given function to every element of the input list. If the result
1111 is `Just x`, then `x` is added to the resulting list.
1113 mapMaybe f lst = [y | x <- lst, Just y = f x]
1116 mapMaybe :: (a -> <e> Maybe b) -> [a] -> <e> [b]
1117 mapMaybe f l = build (\empty cons -> foldl (\cur x -> match f x with Just v -> cons cur v ; _ -> cur) empty l)
1120 Applies the given function to all elements of the list. Produces two lists: the first contains all elements `x`
1121 for which the function returned `Left x` and the second list contains all elements `y` for which the function
1124 mapEither :: (a -> <e> Either b c) -> [a] -> <e> ([b], [c])
1125 mapEither f list = runProc do
1128 for list (\x -> match f x with
1129 Left v -> addArrayList l v
1130 Right v -> addArrayList r v)
1131 (Java.unsafeCoerce l, Java.unsafeCoerce r)
1135 class (Functor f) => FunctorM f where
1136 "`mapM f` is equivalent to `sequence . map f`."
1137 mapM :: Monad m => (a -> m b) -> f a -> m (f b)
1138 "Evaluate each action in the sequence from left to right, and collect the results."
1139 sequence :: Monad m => f (m a) -> m (f a)
1140 mapM f l = sequence (fmap f l)
1144 "Identity function."
1149 Ignores the given value. This function is used in a situation where a function returns
1150 a value in a context where the value is not expected.
1157 ignoreM :: a -> Maybe b
1161 Composes two functions
1164 (.) :: (b -> <e> c) -> (a -> <e> b) -> (a -> <e> c)
1169 "A type class for sequences. All sequences must support indexing by integers."
1170 class /*(Additive a) =>*/ Sequence a where
1171 "Length of the sequence"
1172 length :: a -> Integer
1173 "`take n s` returns the first `n` elements of the sequence `s`."
1174 take :: Integer -> a -> a
1175 "`drop n s` removes the first `n` elements of the sequence `s`."
1176 drop :: Integer -> a -> a
1178 `sub s begin end` returns a subsequence of `s` starting from
1179 index `begin` and ending just before index `end`.
1181 sub :: a -> Integer -> Integer -> a
1183 take n v = sub v 0 (min n (length v))
1184 drop n v = sub v (min n len) len
1188 instance Sequence [a] where
1192 instance Sequence String where
1193 length = lengthString
1196 class IndexedSequence f where
1197 "`seq ! i` returns the `i`th element of the sequence `seq`. Indexing starts from zero."
1198 (!) :: f a -> Integer -> a
1200 instance IndexedSequence [] where
1206 Equivalent to the boolean value `True`. The value is meant to be used in
1213 otherwise :: Boolean
1216 instance Eq Boolean where
1217 a == b = if a then b else not b
1218 a != b = if a then not b else b
1220 instance Ord Boolean where
1221 compare False False = 0
1222 compare False True = neg 1
1223 compare True False = 1
1224 compare True True = 0
1226 instance Show Boolean where
1228 show False = "False"
1231 Boolean conjunction (and). The function is a macro that evaluates the second parameter
1232 only if the first parameter is `True`.
1235 <tr><th>a</th><th>b</th><th>a && b</th></tr>
1236 <tr><td>True</td><td>True</td><td>True</td></tr>
1237 <tr><td>True</td><td>False</td><td>False</td></tr>
1238 <tr><td>False</td><td>not evaluated</td><td>False</td></tr>
1242 (&&) :: Boolean -> Boolean -> Boolean
1243 a && b = if a then b else False
1246 Boolean disjunction (or). The function is a macro that evaluates the second parameter
1247 only if the first parameter is `False`.
1250 <tr><th>a</th><th>b</th><th>a || b</th></tr>
1251 <tr><td>True</td><td>not evaluated</td><td>True</td></tr>
1252 <tr><td>False</td><td>True</td><td>True</td></tr>
1253 <tr><td>False</td><td>False</td><td>False</td></tr>
1257 (||) :: Boolean -> Boolean -> Boolean
1258 a || b = if a then True else b
1262 not a = if a then False else True
1266 //data Maybe a = Nothing | Just a
1268 "Given `Just x` this function returns `x`. If the parameter is `Nothing`, the function raises an exception."
1269 fromJust :: Maybe a -> a
1270 fromJust (Just a) = a
1272 deriving instance (Eq a) => Eq (Maybe a)
1273 deriving instance (Ord a) => Ord (Maybe a)
1274 deriving instance (Show a) => Show (Maybe a)
1275 deriving instance (Hashable a) => Hashable (Maybe a)
1277 instance Functor Maybe where
1278 fmap _ Nothing = Nothing
1279 fmap f (Just x) = Just (f x)
1281 instance FunctorE Maybe where
1282 map _ Nothing = Nothing
1283 map f (Just x) = Just (f x)
1286 iter f (Just x) = ignore (f x)
1288 iterI _ Nothing = ()
1289 iterI f (Just x) = ignore (f 0 x)
1291 instance Monad Maybe where
1295 Nothing >>= _ = Nothing
1299 join Nothing = Nothing
1302 instance MonadZero Maybe where
1305 instance MonadOr Maybe where
1306 morelse a@(Just _) _ = a
1309 "`execJust v f` executes the function `f` with parameter value `x`, if `v=Just x`. If `v=Nothing`, the function does nothing."
1311 execJust :: Maybe a -> (a -> <e> b) -> <e> ()
1312 execJust maybeValue procedure = match maybeValue with
1313 Just v -> ignore $ procedure v
1316 "`fromMaybe def v` returns `def` if `v=Nothing` and `x` if `v=Just x`."
1318 fromMaybe :: a -> Maybe a -> a
1319 fromMaybe default maybeValue = match maybeValue with
1325 Provides a default value if the first parameter is Nothing.
1326 The default value is evaluated only if needed. The function
1327 can be used as an operator and is right associative so that
1328 the following is possible:
1330 tryWithTheFirstMethod
1331 `orElse` tryWithTheSecondMethod
1332 `orElse` fail "Didn't succeed."
1335 orElse :: Maybe a -> (<e> a) -> <e> a
1336 orElse (Just x) _ = x
1337 orElse Nothing def = def
1342 The Either type represents values with two possibilities: a value of type `Either a b` is either `Left a` or `Right b`.
1344 The `Either` type is sometimes used to represent a value which is either correct or an error; by convention, the `Left` constructor
1345 is used to hold an error value and the `Right` constructor is used to hold a correct value (mnemonic: "right" also means "correct").
1347 data Either a b = Left a | Right b
1349 deriving instance (Eq a, Eq b) => Eq (Either a b)
1350 deriving instance (Ord a, Ord b) => Ord (Either a b)
1351 deriving instance (Show a, Show b) => Show (Either a b)
1352 deriving instance (Hashable a, Hashable b) => Hashable (Either a b)
1354 instance Functor (Either a) where
1355 fmap _ (Left x) = Left x
1356 fmap f (Right y) = Right (f y)
1358 instance FunctorE (Either a) where
1359 map _ (Left x) = Left x
1360 map f (Right y) = Right (f y)
1362 iter _ (Left x) = ()
1363 iter f (Right y) = ignore (f y)
1365 iterI _ (Left x) = ()
1366 iterI f (Right y) = ignore (f 0 y)
1368 instance Monad (Either b) where
1371 Left x >>= _ = Left x
1374 join (Left x) = Left x
1379 importJava "java.lang.String" where
1382 concatString :: String -> String -> String
1384 @JavaName "compareTo"
1385 compareString :: String -> String -> Integer
1387 // @JavaName "hashCode"
1388 // hashString :: String -> Integer
1391 equalsString :: String -> String -> Boolean
1394 lengthString :: String -> Integer
1397 `replaceString original pattern replacement` replaces all occurrences of `pattern` in the string by `replacement`.
1400 replaceString :: String -> String -> String -> String
1404 splitString_ :: String -> String -> Array String
1407 `indexOf string s` finds the first occurrence of `s` from `string` and returns its index.
1408 If the `s` does not occur in the string, return `-1`."
1411 indexOf :: String -> String -> Integer
1413 "Works like `indexOf` but starts searching from the given index instead of the beginning of the string."
1415 indexOfStartingFrom :: String -> String -> Integer -> Integer
1417 "Works like `indexOf` but returns the index of the last occurrence."
1418 @JavaName lastIndexOf
1419 lastIndexOf :: String -> String -> Integer
1421 "Works like `lastIndexOf` but starts searching from the given index instead of the end of the string."
1422 @JavaName lastIndexOf
1423 lastIndexOfStartingFrom :: String -> String -> Integer -> Integer
1427 subString :: String -> Integer -> Integer -> String
1430 `regionMatches str1 offset1 str2 offset2 len` tests whether
1431 `sub str1 offset1 (offset1+len) == sub str2 offset2 (offset2+len)`.
1433 regionMatches :: String -> Integer -> String -> Integer -> Integer -> Boolean
1435 "`startsWith string prefix` returns true if the string begins with the given prefix."
1436 startsWith :: String -> String -> Boolean
1438 "`endsWith string suffix` returns true if the string ends with the given prefix."
1439 endsWith :: String -> String -> Boolean
1441 "Removes leading and trailing whitespace from the string."
1442 trim :: String -> String
1444 "`contains string s` returns true if `string` contains `s` as a substring."
1445 contains :: String -> String -> Boolean
1447 "`charAt string i` returns the `i`th character of the string."
1448 charAt :: String -> Integer -> Character
1450 "Converts all letters of the string to lower case."
1451 toLowerCase :: String -> String
1452 "Converts all letters of the string to upper case."
1453 toUpperCase :: String -> String
1455 "Creates a string from a vector of characters."
1457 string :: Vector Character -> String
1459 instance Eq String where
1462 instance Hashable String where
1463 hashP x v = Java.hashCode x + v*16777619
1465 instance Ord String where
1466 compare = compareString
1468 instance Additive String where
1471 sum ss = runProc (StringBuilder.toString $ foldl StringBuilder.appendString StringBuilder.new ss)
1474 importJava "org.simantics.scl.runtime.string.StringEscape" where
1475 appendEscapedString :: StringBuilder.T -> String -> <Proc> StringBuilder.T
1477 instance Show String where
1478 showForPrinting = id
1479 sb <+ v = (appendEscapedString (sb << "\"") v) << "\""
1481 instance Read String where
1484 "`splitString text pattern` splits the string into a list of string where the parts are sepratated in the original list by the given pattern."
1485 splitString :: String -> String -> [String]
1486 splitString source pattern = arrayToList $ splitString_ source pattern
1488 split :: String -> String -> [String]
1489 split pattern text = arrayToList $ splitString_ text pattern
1493 instance Eq () where
1496 instance Ord () where
1499 instance Hashable () where
1502 instance Additive () where
1506 instance Show () where
1511 "Gives the first element of a pair."
1516 "Gives the second element of a pair."
1521 instance (Eq a, Eq b) => Eq (a, b) where
1522 (a0, b0) == (a1, b1) = a0 == a1 && b0 == b1
1524 instance (Ord a, Ord b) => Ord (a, b) where
1525 compare (a0, b0) (a1, b1) = compare a0 a1 &<& compare b0 b1
1527 instance (Hashable a, Hashable b) => Hashable (a, b) where
1528 hashP (a,b) x = hashP b $ hashP a x
1530 instance (Additive a, Additive b) => Additive (a, b) where
1532 (a0, b0) + (a1, b1) = (a0+a1, b0+b1)
1534 instance Functor ((,) a) where
1535 fmap f (a,b) = (a, f b)
1537 instance (Show a, Show b) => Show (a, b) where
1538 sb <+ (x, y) = sb << "(" <+ x << ", " <+ y << ")"
1542 instance (Eq a, Eq b, Eq c) => Eq (a, b, c) where
1543 (a0, b0, c0) == (a1, b1, c1) = a0 == a1 && b0 == b1 && c0 == c1
1545 instance (Ord a, Ord b, Ord c) => Ord (a, b, c) where
1546 compare (a0, b0, c0) (a1, b1, c1) = compare a0 a1 &<& compare b0 b1 &<& compare c0 c1
1548 instance (Hashable a, Hashable b, Hashable c) => Hashable (a, b, c) where
1549 hashP (a,b,c) x = hashP c $ hashP b $ hashP a x
1551 instance (Additive a, Additive b, Additive c) => Additive (a, b, c) where
1552 zero = (zero, zero, zero)
1553 (a0, b0, c0) + (a1, b1, c1) = (a0+a1, b0+b1, c0+c1)
1555 instance Functor ((,,) a b) where
1556 fmap f (a,b,c) = (a, b, f c)
1558 instance (Show a, Show b, Show c) => Show (a, b, c) where
1559 sb <+ (x, y, z) = sb << "(" <+ x << ", " <+ y << ", " <+ z << ")"
1563 instance (Eq a, Eq b, Eq c, Eq d) => Eq (a, b, c, d) where
1564 (a0, b0, c0, d0) == (a1, b1, c1, d1) = a0 == a1 && b0 == b1 && c0 == c1 && d0 == d1
1566 instance (Ord a, Ord b, Ord c, Ord d) => Ord (a, b, c, d) where
1567 compare (a0, b0, c0, d0) (a1, b1, c1, d1) =
1568 compare a0 a1 &<& compare b0 b1 &<& compare c0 c1 &<& compare d0 d1
1570 instance (Hashable a, Hashable b, Hashable c, Hashable d) => Hashable (a, b, c, d) where
1571 hashP (a,b,c,d) x = hashP d $ hashP c $ hashP b $ hashP a x
1573 instance (Additive a, Additive b, Additive c, Additive d) => Additive (a, b, c, d) where
1574 zero = (zero, zero, zero, zero)
1575 (a0, b0, c0, d0) + (a1, b1, c1, d1) = (a0+a1, b0+b1, c0+c1, d0+d1)
1577 instance Functor ((,,,) a b c) where
1578 fmap f (a,b,c,d) = (a, b, c, f d)
1580 instance (Show a, Show b, Show c, Show d) => Show (a, b, c, d) where
1581 sb <+ (x, y, z, w) = sb << "(" <+ x << ", " <+ y << ", " <+ z << ", " <+ w << ")"
1585 instance (Eq a, Eq b, Eq c, Eq d, Eq e) => Eq (a, b, c, d, e) where
1586 (a0, b0, c0, d0, e0) == (a1, b1, c1, d1, e1) =
1587 a0 == a1 && b0 == b1 && c0 == c1 && d0 == d1 && e0 == e1
1589 instance (Ord a, Ord b, Ord c, Ord d, Ord e) => Ord (a, b, c, d, e) where
1590 compare (a0, b0, c0, d0, e0) (a1, b1, c1, d1, e1) =
1591 compare a0 a1 &<& compare b0 b1 &<& compare c0 c1 &<& compare d0 d1 &<& compare e0 e1
1593 instance (Hashable a, Hashable b, Hashable c, Hashable d, Hashable e)
1594 => Hashable (a, b, c, d, e) where
1595 hashP (a,b,c,d,e) x = hashP e $ hashP d $ hashP c $ hashP b $ hashP a x
1597 instance (Additive a, Additive b, Additive c, Additive d, Additive e) => Additive (a, b, c, d, e) where
1598 zero = (zero, zero, zero, zero, zero)
1599 (a0, b0, c0, d0, e0) + (a1, b1, c1, d1, e1) = (a0+a1, b0+b1, c0+c1, d0+d1, e0+e1)
1601 instance Functor ((,,,,) a b c d) where
1602 fmap f (a,b,c,d,e) = (a, b, c, d, f e)
1606 instance (Eq a) => Eq [a] where
1607 a == b = lA == lB && loop 0
1611 loop i = i>=lA || (a!i == b!i && loop (i+1))
1613 instance (Ord a) => Ord [a] where
1614 compare a b = loop 0
1619 then (if i >= lB then 0 else -1)
1622 else compare (a!i) (b!i) &<& loop (i+1)
1624 instance (Hashable a) => Hashable [a] where
1625 hashP a x = loop 0 x
1628 loop i x = if i == lA
1630 else loop (i+1) (hashP (a!i) x)
1632 instance Functor [] where
1635 instance FunctorE [] where
1640 instance Monad [] where
1641 return x = singletonList x
1642 l >>= f = concatMap f l
1645 instance MonadZero [] where
1648 instance MonadPlus [] where
1651 instance Additive [a] where
1655 instance FunctorM [] where
1656 sequence = foldl (\m mel -> m >>= \l -> mel >>= \el -> return (addList l el)) (return emptyList)
1657 mapM f l = sequence (map f l)
1659 "Appends the string representations of all elements of the list to the string builder and separates the values with the given separator."
1660 printWithSeparator :: Show a => StringBuilder.T -> String -> [a] -> <Proc> StringBuilder.T
1661 printWithSeparator sb sep l = loop 0
1664 loop i = if i >= len then sb
1666 (if i==0 then sb else sb << sep) <+ l!i
1669 "Joins the string representations of the list of values with the given separator."
1670 joinWithSeparator :: Show a => String -> [a] -> String
1671 joinWithSeparator separator values = runProc (
1672 StringBuilder.toString $ printWithSeparator StringBuilder.new separator values)
1674 instance (Show a) => Show [a] where
1679 if (i>0) then sb << ", " else sb
1686 importJava "java.util.List" where
1687 "`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."
1689 getList :: [a] -> Integer -> a
1693 lengthList :: [a] -> Integer
1696 subList :: [a] -> Integer -> Integer -> [a]
1699 isEmpty :: [a] -> Boolean
1702 importJava "java.util.Collections" where
1704 //singletonList :: a -> [a]
1709 emptyList = build (\empty cons -> empty)
1712 "Creates a list with exectly one element."
1714 singletonList :: a -> [a]
1715 singletonList v = build (\empty cons -> cons empty v)
1718 // foldl f i (a + b) = foldl f (foldl f i a) b
1720 appendList :: [a] -> [a] -> [a]
1721 appendList a b = build (\empty cons -> foldl cons (foldl cons empty a) b)
1724 importJava "org.simantics.scl.runtime.list.ShareableList" where
1725 "Concatenates two lists."
1728 appendList :: [a] -> [a] -> [a]
1730 "Adds the given value to the end of the list."
1732 addList :: [a] -> a -> [a]
1735 importJava "java.util.ArrayList" where
1739 newArrayList :: <Proc> ArrayList a
1742 addArrayList :: ArrayList a -> a -> <Proc> ()
1745 A primitive for constructing a list by `empty` and `cons` operations given to the function given as a parameter to this function.
1748 build (\empty cons -> cons (cons (cons empty 1) 2) 3)
1754 The SCL compiler makes the following optimization when encountering `build` and `foldl` functions after inlining:
1756 foldl f i (build g) = g i f
1759 build :: forall b e2. (forall a e1. a -> (a -> b -> <e1> a) -> <e1,e2> a) -> <e2> [b]
1760 build f = runProc do
1762 f () (\_ v -> addArrayList l v)
1765 "A specific implementation of `map` for lists."
1768 mapEList :: (a -> <e> b) -> [a] -> <e> [b]
1769 mapEList f l = build (\empty cons -> foldl (\cur x -> cons cur (f x)) empty l)
1771 "A specific implementation of `fmap` for lists."
1773 mapList :: (a -> b) -> [a] -> [b]
1774 mapList f l = build (\empty cons -> foldl (\cur x -> cons cur (f x)) empty l)
1776 "`guardList v` returns a singleton `[()]` if `v=True` and the empty list if `v=False`."
1778 guardList :: Boolean -> [()]
1779 guardList cond = build (\empty cons -> if cond then cons empty () else empty)
1782 `concatMap` combines `map` and `join` functions.
1783 It maps the elements of a given list to lists with the given function and concatenates the results.
1785 concatMap f lst = join (map f lst) = [y | x <- lst, y <- f x]
1788 concatMap :: (a -> <e> [b]) -> [a] -> <e> [b]
1789 concatMap f l = build (\empty cons -> foldl (\cur le -> foldl cons cur (f le)) empty l)
1792 Applies the given function to the elements of the lists until the function returns something
1793 else than `Nothing`. This return value is also returned as a result of this function.
1796 mapFirst :: (a -> <e> Maybe b) -> [a] -> <e> Maybe b
1797 mapFirst f l = loop 0
1800 loop i = if i == len
1802 else match f (l!i) with
1804 Nothing -> loop (i+1)
1807 foldl op initialValue list
1809 applies a binary operator `op` to all elements of `list` from left to right
1810 starting with `initialValue`. For example,
1812 foldl op init [x1, x2, x3, x4] = (((init `op` x1) `op` x2) `op` x3) `op` x4
1815 foldl :: forall a b e. (a -> b -> <e> a) -> a -> [b] -> <e> a
1816 foldl f initial l = loop initial 0
1819 loop cur i = if i==len
1821 else loop (f cur (l!i)) (i+1)
1823 foldlI :: forall a b e. (Integer -> a -> b -> <e> a) -> a -> [b] -> <e> a
1824 foldlI f initial l = loop initial 0
1827 loop cur i = if i==len
1829 else loop (f i cur (l!i)) (i+1)
1831 scanl :: (b -> a -> <e> b) -> b -> [a] -> <e> [b]
1832 scanl f initial l = build (\empty cons -> let
1834 loop cur i accum = let nl = cons accum cur
1837 else loop (f cur (l!i)) (i+1) nl
1838 in loop initial 0 empty)
1840 "`foldr` is defined like `foldl` but it process the list from right to left."
1842 foldr :: (b -> a -> <e> a) -> a -> [b] -> <e> a
1843 foldr f initial l = loop initial (length l - 1)
1845 loop cur i = if i < 0
1847 else loop (f (l!i) cur) (i-1)
1849 foldr1 :: (a -> a -> <e> a) -> [a] -> <e> a
1850 foldr1 f l = loop (l!(len-1)) (len-2)
1853 loop cur i = if i < 0
1855 else loop (f (l!i) cur) (i-1)
1858 `filter pred lst` returns those elements of `lst` that the predicate `pred` accepts. For example
1860 filter (> 3) [1, 2, 3, 4, 5, 6] = [4, 5, 6]
1863 filter :: (a -> <e> Boolean) -> [a] -> <e> [a]
1864 filter p l = build (\empty cons -> foldl (\cur x -> if p x then cons cur x else cur) empty l)
1867 Takes those elements of the input list that match `(Just x)` and adds the contents to the resulting list. For example,
1869 filterJust [Just 1, Nothing, Just 5] = [1, 5]
1872 filterJust :: [Maybe a] -> [a]
1873 filterJust l = build (\empty cons -> foldl (\cur x -> match x with Just v -> cons cur v ; _ -> cur) empty l)
1875 listToMaybe :: [a] -> Maybe a
1876 listToMaybe l = if isEmpty l then Nothing else Just (l!0)
1878 maybeToList :: Maybe a -> [a]
1879 maybeToList (Just a) = [a]
1883 `takeWhile p l`, returns the longest prefix (possibly empty) of list `l` of elements that satisfy `p`
1885 takeWhile :: (a -> <e> Boolean) -> [a] -> <e> [a]
1886 takeWhile f l = loop 0
1889 loop i | i == len = l
1890 | f (l!i) = loop (i+1)
1891 | otherwise = take i l
1893 partition :: (a -> <e> Boolean) -> [a] -> <e> ([a], [a])
1894 partition p l = runProc do
1899 then addArrayList res1 el
1900 else addArrayList res2 el
1902 (Java.unsafeCoerce res1, Java.unsafeCoerce res2)
1905 `range begin end` produces a list of consecutive integers starting from `begin` and ending to `end` (including `end`).
1906 The compiler supports syntactic sugar `[begin..end]` for this function.
1909 range :: Integer -> Integer -> [Integer]
1910 range first last = build (\empty cons -> do
1911 loop i cur = if i > last then cur else loop (i+1) (cons cur i)
1914 "A specific implementation of `iter` for lists."
1916 iterList :: (a -> <e> b) -> [a] -> <e> ()
1917 iterList f l = foldl (\_ x -> ignore (f x)) () l
1919 "A specific implementation of `iterI` for lists."
1921 iterIList :: (Integer -> a -> <e> b) -> [a] -> <e> ()
1922 iterIList f l = do foldl (\i x -> do f i x ; i+1) 0 l ; ()
1925 Generates a list from a given starting state and iteration function.
1928 let nextState 0 = Nothing
1929 nextState i = Just (i, i `div` 2)
1930 in unfoldr nextState 30
1937 unfoldr :: (b -> <e> Maybe (a, b)) -> b -> <e> [a]
1938 unfoldr f s = build (\empty cons -> do
1941 Just (el,newS) -> loop newS (cons cur el)
1945 importJava "org.simantics.scl.runtime.Lists" where
1949 mapList :: (a -> b) -> [a] -> [b]
1952 mapEList :: (a -> <e> b) -> [a] -> <e> [b]
1955 iterList :: (a -> <e> ()) -> [a] -> <e> ()
1956 concatMap :: (a -> <e> [b]) -> [a] -> <e> [b]
1959 Combines two lists into one list of pairs. The length of the resulting list is the length of the smallest input list.
1961 zip [1, 2, 3, 4, 5] ['a', 'b', 'c'] = [(1, 'a'), (2, 'b'), (3, 'c')]
1963 zip :: [a] -> [b] -> [(a,b)]
1964 "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."
1965 zipWith :: (a -> b -> <e> c) -> [a] -> [b] -> <e> [c]
1967 Produces two lists from one list of pairs.
1969 unzip [(1, 'a'), (2, 'b'), (3, 'c')] = ([1, 2, 3], ['a', 'b', 'c'])
1971 unzip :: [(a,b)] -> ([a],[b])
1973 //"@filter p l@ returns those elements of @l@ that the predicate @p@ accepts."
1974 //filter :: (a -> <e> Boolean) -> [a] -> <e> [a]
1975 //filterJust :: [Maybe a] -> [a]
1977 foldl :: (a -> b -> <e> a) -> a -> [b] -> <e> a
1979 "Like `foldl` but assumes that the list is non-empty so the initial is not needed."
1980 foldl1 :: (a -> a -> <e> a) -> [a] -> <e> a
1981 //unfoldr :: (b -> <e> Maybe (a, b)) -> b -> <e> [a]
1983 "Sorts the list using the given comparator."
1984 sortWith :: (a -> a -> <e> Integer) -> [a] -> <e> [a]
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 groupWith :: (b -> Integer) -> (b -> b -> Boolean) -> (a -> <e> b) -> (a -> <e> c) -> [a] -> <e> [(b, [c])]
1988 "Works like `unique` but uses the given function for equality tests."
1989 uniqueWith :: (a -> a -> Boolean) -> [a] -> [a]
1990 "Works like `\\\\` but uses the given function for equality tests."
1991 deleteAllBy :: (a -> a -> Boolean) -> [a] -> [a] -> [a]
1993 //range :: Integer -> Integer -> [Integer]
1995 //build :: (forall a. a -> (a -> b -> <e> a) -> <e> a) -> <e> [b]
1997 "`elem el lst` return true, if `el` occurs in the list `lst`."
1998 elem :: Eq a => a -> [a] -> Boolean
2002 loop i | i < len = if el == l!i
2007 "`elemMaybe v1 (Just v2)` returns true if `v1 == v2`. `elemMaybe v1 Nothing` is always false."
2008 elemMaybe :: Eq a => a -> Maybe a -> Boolean
2009 elemMaybe el m = match m with
2010 Just el2 -> el == el2
2014 Computes a list that contains only elements that belongs to both input lists.
2016 intersect :: Eq a => [a] -> [a] -> [a]
2017 intersect a b = filter f a
2021 "Reverses a given list. For example, `reverse [1,2,3] = [3,2,1]`"
2022 reverse :: [a] -> [a]
2023 reverse l = [l!(len-i) | i <- [1..len]]
2028 Transposes the rows and columns of its argument. For example,
2030 transpose [[1,2,3],[4,5,6]] == [[1,4],[2,5],[3,6]]
2031 transpose [[1,2],[3,4,5]] == [[1,3],[2,4],[5]]
2033 transpose xss = [[xs!i | xs <- xss, i < length xs]
2034 | i <- [0..maximum [length xs | xs <- xss]-1]]
2036 "Works like `unfoldr` but generates the list from right to left."
2037 unfoldl :: (b -> <e> Maybe (a, b)) -> b -> <e> [a]
2038 unfoldl f seed = reverse $ unfoldr f seed
2040 "Removes the first element of the list, if the list is non-empty."
2042 tail l = if len < 2 then emptyList else subList l 1 len
2046 "Tries to find the given key from the list of key-value pairs and returns the corresponding value."
2047 lookup :: Eq a => a -> [(a, b)] -> Maybe b
2052 (a,b) | a == el -> Just b
2053 | otherwise -> loop (i+1)
2057 "Conjunction over a list."
2059 and :: [Boolean] -> Boolean
2060 and = foldl (&&) True
2062 "Disjunction over a list."
2064 or :: [Boolean] -> Boolean
2065 or = foldl (||) False
2068 `any pred lst` tests whether the predicate `pred` holds some element of `lst`.
2069 It returns immediately when it encounters the first value satisfying the predicate.
2071 any :: (a -> <e> Boolean) -> [a] -> <e> Boolean
2075 `all pred lst` tests whether the predicate `pred` holds for all elements of `lst`.
2076 It returns immediately when it encounters the first value not satisfying the predicate.
2078 all :: (a -> <e> Boolean) -> [a] -> <e> Boolean
2082 Returns the first element of the list satisfying the given condition,
2083 or `Nothing` if there is no such element.
2085 findFirst :: (a -> <e> Boolean) -> [a] -> <e> Maybe a
2086 findFirst p l = loop 0
2090 then let el = l!i in
2099 Sorts the given list using its default order.
2102 sort :: Ord a => [a] -> [a]
2103 sort = sortWith compare
2106 Sorts the lists by the values computed by the first function.
2109 sortBy snd [(1,5), (2,3), (3,4)] = [(2,3), (3,4), (1,5)]
2112 sortBy :: Ord b => (a -> <e> b) -> [a] -> <e> [a]
2113 sortBy f l = sortWith (\x y -> compare (f x) (f y)) l
2114 // This is faster if f is slow, but will generate more auxiliary structures
2115 //sortBy f l = map snd (sortWith (\(x,_) (y,_) -> compare x y) [(f x, x) | x <- l])
2118 Given a list of key-value pairs, the function produces a function that finds a value
2119 efficiently for the given key.
2121 index :: Hashable a => [(a,b)] -> a -> Maybe b
2122 index = indexWith hash (==)
2125 Given a list of values and a function computing a key for each value, the function produces a function that finds a value
2126 effeciently for the given key.
2128 indexBy :: Hashable b => (a -> b) -> [a] -> b -> Maybe a
2129 indexBy f l = index [(f x, x) | x <- l]
2131 "Groups a list values by a key computed by the given function."
2132 groupBy :: Hashable b => (a -> <e> b) -> [a] -> <e> [(b, [a])]
2133 groupBy f l = groupWith hash (==) f id l
2135 "Groups a list of key-value pairs by the keys."
2136 group :: Hashable a => [(a,b)] -> [(a, [b])]
2137 group = groupWith hash (==) fst snd
2139 "Removes duplicates (all but the first occurrence) from the list but otherwise preserves the order of the elements."
2140 unique :: Eq a => [a] -> [a]
2141 unique = uniqueWith (==)
2143 "Like `unique`, but uses the given function for finding the key values used for uniqueness testing."
2144 uniqueBy :: Eq b => (a -> b) -> [a] -> [a]
2145 uniqueBy f = uniqueWith (\a b -> f a == f b)
2147 //sortAndUniqueBy :: Ord b => (a -> b) -> [a] -> [a]
2148 //sortAndUniqueBy f = map snd . uniqueWith (\a b -> fst a == fst b) . sortBy fst . map (\x -> (f x, x))
2150 "`a \\\\ b` removes all elements of `b` from the list `a`."
2151 (\\) :: Eq a => [a] -> [a] -> [a]
2152 (\\) = deleteAllBy (==)
2156 importJava "java.lang.Object" where
2157 "A data type that can represent any value."
2162 showDynamic :: Dynamic -> String
2164 instance Show Dynamic where
2167 "Converts a value to `Dynamic` type."
2168 toDynamic :: a -> Dynamic
2169 toDynamic = Java.unsafeCoerce
2171 "Converts a `Dynamic` value to a required value, or fails if the conversion is not possible."
2172 importJava "org.simantics.scl.compiler.runtime.ValueConversion" where
2173 fromDynamic :: Typeable a => Dynamic -> a
2177 importJava "org.simantics.scl.runtime.procedure.Ref" where
2178 "A mutable reference to a value of type `a`."
2181 "Creates a new reference with the given initial value."
2183 ref :: a -> <Proc> (Ref a)
2185 "Returns the current value of the reference."
2187 getRef :: Ref a -> <Proc> a
2189 "Sets a new value for the reference."
2190 @JavaName "<set>value"
2191 (:=) :: Ref a -> a -> <Proc> ()
2193 instance Show (Ref a) where
2194 show _ = "<reference>"
2196 importJava "org.simantics.scl.runtime.reporting.SCLReporting" where
2197 "Prints the given string to the console."
2199 printString :: String -> <Proc> ()
2200 "Prints an error message to the console."
2201 printError :: String -> <Proc> ()
2202 "Reports that certain amount of work has been done for the current task."
2203 didWork :: Double -> <Proc> ()
2205 `printingToFile "fileName" expression` executes the `expression` so that all its console prints
2206 are written to the file given as a first parameter.
2208 printingToFile :: String -> (<e> a) -> <e> a
2210 `printErrorsAsNormalPrints expression` executes the `expression` so that all its error prints
2211 are printed as normal prints. This is useful mainly in testing scripts for checking that the implementations
2212 give proper error messages with invalid inputs.
2214 printErrorsAsNormalPrints :: (<e> a) -> <e> a
2216 `disablePrintingForCommand expression` executes the `expression` so that it does not print return values.
2217 Errors are printed normally.
2219 disablePrintingForCommand :: (<e> a) -> <e> a
2222 importJava "org.simantics.scl.runtime.procedure.Procedures" where
2223 "Returns `True` if the current thread has been interrupted."
2224 isInterrupted :: <Proc> Boolean
2225 "Checks whether the current thread has been interrupted and throws an exception if it is."
2226 checkInterrupted :: <Proc> ()
2227 "Generates a random identifier."
2228 generateUID :: <Proc> String
2230 "Executes the given expression and catches certain class of exceptions (specified by the catch handler that is given as a second parameter.)"
2232 catch :: VecComp ex => (<e> a) -> (ex -> <e> a) -> <e> a
2234 importJava "java.lang.Throwable" where
2238 showThrowable :: Throwable -> String
2239 importJava "java.lang.Exception" where
2243 showException :: Exception -> String
2245 instance Show Throwable where
2246 show = showThrowable
2247 instance Show Exception where
2248 show = showException
2250 "Prints the given value in the console."
2252 print :: Show a => a -> <Proc> ()
2253 print v = printString (showForPrinting v)
2255 instance Show TypeRep where
2256 sb <+ (TApply (TCon "Builtin" "[]") b) =
2257 sb << "[" <+ b << "]"
2258 sb <+ (TApply (TApply (TCon "Builtin" "(,)") c1) c2) =
2259 sb << "(" <+ c1 << "," <+ c2 << ")"
2260 sb <+ (TApply (TApply (TApply (TCon "Builtin" "(,,)") c1) c2) c3) =
2261 sb << "(" <+ c1 << "," <+ c2 << "," <+ c3 << ")"
2262 sb <+ (TApply (TApply (TApply (TApply (TCon "Builtin" "(,,,)") c1) c2) c3) c4) =
2263 sb << "(" <+ c1 << "," <+ c2 << "," <+ c3 << "," <+ c4 << ")"
2265 sb <+ (TCon _ name) = sb << name
2266 sb <+ (TApply a b) = sb <+ Par 1 a << " " <+ Par 2 b
2267 sb <+ (TFun a b) = sb <+ Par 1 a << " -> " <+ b
2269 precedence (TCon _ _) = 0
2270 precedence (TFun _ _) = 2
2271 precedence (TApply a _) = if isSpecialType a then 0 else 1
2273 isSpecialType (TCon "Builtin" "[]") = True
2274 isSpecialType (TCon "Builtin" "()") = True
2275 isSpecialType (TCon "Builtin" "(,)") = True
2276 isSpecialType (TCon "Builtin" "(,,)") = True
2277 isSpecialType (TCon "Builtin" "(,,,)") = True
2278 isSpecialType (TApply a _) = isSpecialType a
2283 importJava "java.util.Arrays" where
2286 byteArrayToString :: ByteArray -> String
2288 instance Show ByteArray where
2289 show = byteArrayToString
2294 importJava "org.simantics.scl.compiler.types.Type" where
2296 showType :: Type -> String
2298 importJava "org.simantics.scl.compiler.types.Types" where
2299 removeForAll :: Type -> Type
2301 instance Show Type where