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]
1882 partition :: (a -> <e> Boolean) -> [a] -> <e> ([a], [a])
1883 partition p l = runProc do
1888 then addArrayList res1 el
1889 else addArrayList res2 el
1891 (Java.unsafeCoerce res1, Java.unsafeCoerce res2)
1894 `range begin end` produces a list of consecutive integers starting from `begin` and ending to `end` (including `end`).
1895 The compiler supports syntactic sugar `[begin..end]` for this function.
1898 range :: Integer -> Integer -> [Integer]
1899 range first last = build (\empty cons -> do
1900 loop i cur = if i > last then cur else loop (i+1) (cons cur i)
1903 "A specific implementation of `iter` for lists."
1905 iterList :: (a -> <e> b) -> [a] -> <e> ()
1906 iterList f l = foldl (\_ x -> ignore (f x)) () l
1908 "A specific implementation of `iterI` for lists."
1910 iterIList :: (Integer -> a -> <e> b) -> [a] -> <e> ()
1911 iterIList f l = do foldl (\i x -> do f i x ; i+1) 0 l ; ()
1914 Generates a list from a given starting state and iteration function.
1917 let nextState 0 = Nothing
1918 nextState i = Just (i, i `div` 2)
1919 in unfoldr nextState 30
1926 unfoldr :: (b -> <e> Maybe (a, b)) -> b -> <e> [a]
1927 unfoldr f s = build (\empty cons -> do
1930 Just (el,newS) -> loop newS (cons cur el)
1934 importJava "org.simantics.scl.runtime.Lists" where
1938 mapList :: (a -> b) -> [a] -> [b]
1941 mapEList :: (a -> <e> b) -> [a] -> <e> [b]
1944 iterList :: (a -> <e> ()) -> [a] -> <e> ()
1945 concatMap :: (a -> <e> [b]) -> [a] -> <e> [b]
1948 Combines two lists into one list of pairs. The length of the resulting list is the length of the smallest input list.
1950 zip [1, 2, 3, 4, 5] ['a', 'b', 'c'] = [(1, 'a'), (2, 'b'), (3, 'c')]
1952 zip :: [a] -> [b] -> [(a,b)]
1953 "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."
1954 zipWith :: (a -> b -> <e> c) -> [a] -> [b] -> <e> [c]
1956 Produces two lists from one list of pairs.
1958 unzip [(1, 'a'), (2, 'b'), (3, 'c')] = ([1, 2, 3], ['a', 'b', 'c'])
1960 unzip :: [(a,b)] -> ([a],[b])
1962 //"@filter p l@ returns those elements of @l@ that the predicate @p@ accepts."
1963 //filter :: (a -> <e> Boolean) -> [a] -> <e> [a]
1964 //filterJust :: [Maybe a] -> [a]
1966 foldl :: (a -> b -> <e> a) -> a -> [b] -> <e> a
1968 "Like `foldl` but assumes that the list is non-empty so the initial is not needed."
1969 foldl1 :: (a -> a -> <e> a) -> [a] -> <e> a
1970 //unfoldr :: (b -> <e> Maybe (a, b)) -> b -> <e> [a]
1972 "Sorts the list using the given comparator."
1973 sortWith :: (a -> a -> <e> Integer) -> [a] -> <e> [a]
1974 "Works like `index` but uses the given functions as hash codes and equality."
1975 indexWith :: (a -> Integer) -> (a -> a -> Boolean) -> [(a,b)] -> a -> Maybe b
1976 groupWith :: (b -> Integer) -> (b -> b -> Boolean) -> (a -> <e> b) -> (a -> <e> c) -> [a] -> <e> [(b, [c])]
1977 "Works like `unique` but uses the given function for equality tests."
1978 uniqueWith :: (a -> a -> Boolean) -> [a] -> [a]
1979 "Works like `\\\\` but uses the given function for equality tests."
1980 deleteAllBy :: (a -> a -> Boolean) -> [a] -> [a] -> [a]
1982 //range :: Integer -> Integer -> [Integer]
1984 //build :: (forall a. a -> (a -> b -> <e> a) -> <e> a) -> <e> [b]
1986 "`elem el lst` return true, if `el` occurs in the list `lst`."
1987 elem :: Eq a => a -> [a] -> Boolean
1991 loop i | i < len = if el == l!i
1996 "`elemMaybe v1 (Just v2)` returns true if `v1 == v2`. `elemMaybe v1 Nothing` is always false."
1997 elemMaybe :: Eq a => a -> Maybe a -> Boolean
1998 elemMaybe el m = match m with
1999 Just el2 -> el == el2
2003 Computes a list that contains only elements that belongs to both input lists.
2005 intersect :: Eq a => [a] -> [a] -> [a]
2006 intersect a b = filter f a
2010 "Reverses a given list. For example, `reverse [1,2,3] = [3,2,1]`"
2011 reverse :: [a] -> [a]
2012 reverse l = [l!(len-i) | i <- [1..len]]
2017 Transposes the rows and columns of its argument. For example,
2019 transpose [[1,2,3],[4,5,6]] == [[1,4],[2,5],[3,6]]
2020 transpose [[1,2],[3,4,5]] == [[1,3],[2,4],[5]]
2022 transpose xss = [[xs!i | xs <- xss, i < length xs]
2023 | i <- [0..maximum [length xs | xs <- xss]-1]]
2025 "Works like `unfoldr` but generates the list from right to left."
2026 unfoldl :: (b -> <e> Maybe (a, b)) -> b -> <e> [a]
2027 unfoldl f seed = reverse $ unfoldr f seed
2029 "Removes the first element of the list, if the list is non-empty."
2031 tail l = if len < 2 then emptyList else subList l 1 len
2035 "Tries to find the given key from the list of key-value pairs and returns the corresponding value."
2036 lookup :: Eq a => a -> [(a, b)] -> Maybe b
2041 (a,b) | a == el -> Just b
2042 | otherwise -> loop (i+1)
2046 "Conjunction over a list."
2048 and :: [Boolean] -> Boolean
2049 and = foldl (&&) True
2051 "Disjunction over a list."
2053 or :: [Boolean] -> Boolean
2054 or = foldl (||) False
2057 `any pred lst` tests whether the predicate `pred` holds some element of `lst`.
2058 It returns immediately when it encounters the first value satisfying the predicate.
2060 any :: (a -> <e> Boolean) -> [a] -> <e> Boolean
2064 `all pred lst` tests whether the predicate `pred` holds for all elements of `lst`.
2065 It returns immediately when it encounters the first value not satisfying the predicate.
2067 all :: (a -> <e> Boolean) -> [a] -> <e> Boolean
2071 Returns the first element of the list satisfying the given condition,
2072 or `Nothing` if there is no such element.
2074 findFirst :: (a -> <e> Boolean) -> [a] -> <e> Maybe a
2075 findFirst p l = loop 0
2079 then let el = l!i in
2088 Sorts the given list using its default order.
2091 sort :: Ord a => [a] -> [a]
2092 sort = sortWith compare
2095 Sorts the lists by the values computed by the first function.
2098 sortBy snd [(1,5), (2,3), (3,4)] = [(2,3), (3,4), (1,5)]
2101 sortBy :: Ord b => (a -> <e> b) -> [a] -> <e> [a]
2102 sortBy f l = sortWith (\x y -> compare (f x) (f y)) l
2103 // This is faster if f is slow, but will generate more auxiliary structures
2104 //sortBy f l = map snd (sortWith (\(x,_) (y,_) -> compare x y) [(f x, x) | x <- l])
2107 Given a list of key-value pairs, the function produces a function that finds a value
2108 efficiently for the given key.
2110 index :: Hashable a => [(a,b)] -> a -> Maybe b
2111 index = indexWith hash (==)
2114 Given a list of values and a function computing a key for each value, the function produces a function that finds a value
2115 effeciently for the given key.
2117 indexBy :: Hashable b => (a -> b) -> [a] -> b -> Maybe a
2118 indexBy f l = index [(f x, x) | x <- l]
2120 "Groups a list values by a key computed by the given function."
2121 groupBy :: Hashable b => (a -> <e> b) -> [a] -> <e> [(b, [a])]
2122 groupBy f l = groupWith hash (==) f id l
2124 "Groups a list of key-value pairs by the keys."
2125 group :: Hashable a => [(a,b)] -> [(a, [b])]
2126 group = groupWith hash (==) fst snd
2128 "Removes duplicates (all but the first occurrence) from the list but otherwise preserves the order of the elements."
2129 unique :: Eq a => [a] -> [a]
2130 unique = uniqueWith (==)
2132 "Like `unique`, but uses the given function for finding the key values used for uniqueness testing."
2133 uniqueBy :: Eq b => (a -> b) -> [a] -> [a]
2134 uniqueBy f = uniqueWith (\a b -> f a == f b)
2136 //sortAndUniqueBy :: Ord b => (a -> b) -> [a] -> [a]
2137 //sortAndUniqueBy f = map snd . uniqueWith (\a b -> fst a == fst b) . sortBy fst . map (\x -> (f x, x))
2139 "`a \\\\ b` removes all elements of `b` from the list `a`."
2140 (\\) :: Eq a => [a] -> [a] -> [a]
2141 (\\) = deleteAllBy (==)
2145 importJava "java.lang.Object" where
2146 "A data type that can represent any value."
2151 showDynamic :: Dynamic -> String
2153 instance Show Dynamic where
2156 "Converts a value to `Dynamic` type."
2157 toDynamic :: a -> Dynamic
2158 toDynamic = Java.unsafeCoerce
2160 "Converts a `Dynamic` value to a required value, or fails if the conversion is not possible."
2161 importJava "org.simantics.scl.compiler.runtime.ValueConversion" where
2162 fromDynamic :: Typeable a => Dynamic -> a
2166 importJava "org.simantics.scl.runtime.procedure.Ref" where
2167 "A mutable reference to a value of type `a`."
2170 "Creates a new reference with the given initial value."
2172 ref :: a -> <Proc> (Ref a)
2174 "Returns the current value of the reference."
2176 getRef :: Ref a -> <Proc> a
2178 "Sets a new value for the reference."
2179 @JavaName "<set>value"
2180 (:=) :: Ref a -> a -> <Proc> ()
2182 instance Show (Ref a) where
2183 show _ = "<reference>"
2185 importJava "org.simantics.scl.runtime.reporting.SCLReporting" where
2186 "Prints the given string to the console."
2188 printString :: String -> <Proc> ()
2189 "Prints an error message to the console."
2190 printError :: String -> <Proc> ()
2191 "Reports that certain amount of work has been done for the current task."
2192 didWork :: Double -> <Proc> ()
2194 `printingToFile "fileName" expression` executes the `expression` so that all its console prints
2195 are written to the file given as a first parameter.
2197 printingToFile :: String -> (<e> a) -> <e> a
2199 `printErrorsAsNormalPrints expression` executes the `expression` so that all its error prints
2200 are printed as normal prints. This is useful mainly in testing scripts for checking that the implementations
2201 give proper error messages with invalid inputs.
2203 printErrorsAsNormalPrints :: (<e> a) -> <e> a
2205 `disablePrintingForCommand expression` executes the `expression` so that it does not print return values.
2206 Errors are printed normally.
2208 disablePrintingForCommand :: (<e> a) -> <e> a
2211 importJava "org.simantics.scl.runtime.procedure.Procedures" where
2212 "Returns `True` if the current thread has been interrupted."
2213 isInterrupted :: <Proc> Boolean
2214 "Checks whether the current thread has been interrupted and throws an exception if it is."
2215 checkInterrupted :: <Proc> ()
2216 "Generates a random identifier."
2217 generateUID :: <Proc> String
2219 "Executes the given expression and catches certain class of exceptions (specified by the catch handler that is given as a second parameter.)"
2221 catch :: VecComp ex => (<e> a) -> (ex -> <e> a) -> <e> a
2223 importJava "java.lang.Throwable" where
2227 showThrowable :: Throwable -> String
2228 importJava "java.lang.Exception" where
2232 showException :: Exception -> String
2234 instance Show Throwable where
2235 show = showThrowable
2236 instance Show Exception where
2237 show = showException
2239 "Prints the given value in the console."
2241 print :: Show a => a -> <Proc> ()
2242 print v = printString (showForPrinting v)
2244 instance Show TypeRep where
2245 sb <+ (TApply (TCon "Builtin" "[]") b) =
2246 sb << "[" <+ b << "]"
2247 sb <+ (TApply (TApply (TCon "Builtin" "(,)") c1) c2) =
2248 sb << "(" <+ c1 << "," <+ c2 << ")"
2249 sb <+ (TApply (TApply (TApply (TCon "Builtin" "(,,)") c1) c2) c3) =
2250 sb << "(" <+ c1 << "," <+ c2 << "," <+ c3 << ")"
2251 sb <+ (TApply (TApply (TApply (TApply (TCon "Builtin" "(,,,)") c1) c2) c3) c4) =
2252 sb << "(" <+ c1 << "," <+ c2 << "," <+ c3 << "," <+ c4 << ")"
2254 sb <+ (TCon _ name) = sb << name
2255 sb <+ (TApply a b) = sb <+ Par 1 a << " " <+ Par 2 b
2256 sb <+ (TFun a b) = sb <+ Par 1 a << " -> " <+ b
2258 precedence (TCon _ _) = 0
2259 precedence (TFun _ _) = 2
2260 precedence (TApply a _) = if isSpecialType a then 0 else 1
2262 isSpecialType (TCon "Builtin" "[]") = True
2263 isSpecialType (TCon "Builtin" "()") = True
2264 isSpecialType (TCon "Builtin" "(,)") = True
2265 isSpecialType (TCon "Builtin" "(,,)") = True
2266 isSpecialType (TCon "Builtin" "(,,,)") = True
2267 isSpecialType (TApply a _) = isSpecialType a
2272 importJava "java.util.Arrays" where
2275 byteArrayToString :: ByteArray -> String
2277 instance Show ByteArray where
2278 show = byteArrayToString
2283 importJava "org.simantics.scl.compiler.types.Type" where
2285 showType :: Type -> String
2287 importJava "org.simantics.scl.compiler.types.Types" where
2288 removeForAll :: Type -> Type
2290 instance Show Type where