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 showDoubleArray :: DoubleArray -> String
46 "Converts an array to a list."
48 arrayToList :: Array a -> [a]
50 importJava "java.util.List" where
51 "Converts a list to an array."
53 listToArray :: [a] -> Array a
55 instance Show DoubleArray where
56 show = showDoubleArray
58 importJava "org.simantics.scl.runtime.Coercion" where
59 "Converts a list of doubles to a double array."
60 toDoubleArray :: [Double] -> DoubleArray
61 "Converts a double array to a list of doubles."
62 fromDoubleArray :: DoubleArray -> [Double]
65 * Precedences and associativity of all operators defined in Prelude
71 infixl 7 (*), (/), div, mod
73 infixl 5 (\\), (<<), (<+)
74 infix 4 (!=), (<), (<=), (>=), (>)
76 infixr 2 (||), orElse, morelse
77 infixr 1 (>>=), (>>), (:=), (>=>)
81 "Creates a constant function. `const x` defines a function that always returns `x`."
87 Function application. `f $ x` is equivalent with `f x`. The function has two uses.
88 First is to remove parentheses from deeply nested expressions:
90 f (g (h x)) == f $ g $ h x
92 The second use is with higher order functions:
94 map ($ parameter) functions
98 ($) :: (a -> <e> b) -> a -> <e> b
101 "Transforms a function taking a pair as a parameter to a function taking two values as a parameter."
103 curry :: ((a, b) -> <e> c) -> a -> b -> <e> c
104 curry f x y = f (x, y)
106 "Transforms a function two values as a parameter to a function taking a pair as a parameter."
108 uncurry :: (a -> b -> <e> c) -> ((a, b) -> <e> c)
109 uncurry f (x, y) = f x y
111 "Transforms a function taking a triple as a parameter to a function taking three values as a parameter."
113 curry3 :: ((a, b, c) -> <e> d) -> a -> b -> c -> <e> d
114 curry3 f x y z = f (x, y, z)
116 "Transforms a function three values as a parameter to a function taking a priple as a parameter."
118 uncurry3 :: (a -> b -> c -> <e> d) -> ((a, b, c) -> <e> d)
119 uncurry3 f (x, y, z) = f x y z
121 "Flips the parameters of a binary function."
123 flip :: (a -> b -> <e> c) -> b -> a -> <e> c
126 "Swaps the order of elements of a pair (2-tuple)."
127 swap :: (a,b) -> (b,a)
133 (!=) :: a -> a -> Boolean
134 a != b = not (a == b)
137 The class of linearly ordered types.
138 Method `compare` must be implemented in instances.
142 `compare x y` returns a negative number, if `x` is smaller than `y`,
143 a positive number, if `x` is bigger than `y` and zero if they are equal.
145 compare :: a -> a -> Integer
146 compare a b = if a < b then -1 else if a > b then 1 else 0
149 (<) :: a -> a -> Boolean
150 a < b = compare a b < 0
152 (<=) :: a -> a -> Boolean
153 a <= b = compare a b <= 0
155 (>) :: a -> a -> Boolean
156 a > b = compare a b > 0
158 (>=) :: a -> a -> Boolean
159 a >= b = compare a b >= 0
161 "Minimum of the parameters"
163 min a b = if a < b then a else b
164 "Maximum of the parameters"
166 max a b = if a > b then a else b
169 Combines two integers such that if the first one is non-zero, it is returned, otherwise
170 the second-one. The second parameter is not implemented, if it is not needed.
172 The function is useful for implementing efficient recursive comparison of structures,
175 compare (x1,y1,z1) (x2,y2,z2) = compare x1 x2 &<& compare y1 y2 &<& compare z1 z2
178 (&<&) :: Integer -> (<e> Integer) -> <e> Integer
179 a &<& b = if a == 0 then b else a
181 "Maximum over a list"
183 maximum :: Ord a => [a] -> a
186 "Minimum over a list"
188 minimum :: Ord a => [a] -> a
191 "As `maximum` but compares the elements by the given projection."
192 maximumBy :: Ord b => (a -> <e> b) -> [a] -> <e> a
193 maximumBy f l = snd $ foldl1 maxF $ map (\x -> (f x, x)) l
195 maxF a b = if fst a >= fst b then a else b
198 As `minimum` but compares the elements by the given projection.
203 returns a pair with the smallest second component.
205 minimumBy :: Ord b => (a -> <e> b) -> [a] -> <e> a
206 minimumBy f l = snd $ foldl1 minF $ map (\x -> (f x, x)) l
208 minF a b = if fst a <= fst b then a else b
212 instance Functor ((->) a) where
215 instance Monad ((->) a) where
217 (m >>= f) x = f (m x) x
220 instance Category (->) where
225 instance (Additive b) => Additive (a -> <e> b) where
227 (f + g) x = f x + g x
229 instance (Ring b) => Ring (a -> <e> b) where
231 (neg f) x = neg (f x)
232 (f - g) x = f x - g x
233 (f * g) x = f x * g x
234 (fromInteger c) x = fromInteger c
236 //instance Show (a -> <e> b) where
237 // show f = "<function>"
239 "Appends a string to the string builder."
240 (<<) :: StringBuilder.T -> String -> <Proc> StringBuilder.T
241 (<<) = StringBuilder.appendString
244 The class of types whose elements can be converted to a string representation.
245 Method `show` or `(<+)` must be implemented.
248 "Converts a value to string."
250 "Appends the string representation of the value to the string builder."
251 (<+) :: StringBuilder.T -> a -> <Proc> StringBuilder.T
253 Returns the precedence of the value. It is used to determine if parenteheses
254 are needed around the string representation of the value. The default value is 0
255 and means that parentheses are never added.
257 precedence :: a -> Integer
259 "Converts a value to a string like `show` but does not put string literals in double quotes."
260 showForPrinting :: a -> String
262 show v = runProc (StringBuilder.toString (StringBuilder.new <+ v))
263 showForPrinting v = show v
264 sb <+ v = StringBuilder.appendString sb (show v)
268 `Par` data type is used to control the placement of parentheses when converting values to string.
269 Value `Par prec val` is converted to string like `val` but parentheses are put around, if the
270 precedence of the value is greater than `prec`.
272 data Par a = Par Integer a
274 instance (Show a) => Show (Par a) where
275 sb <+ (Par outerPrec v) = if prec > outerPrec
276 then sb << "(" <+ v << ")"
278 where prec = precedence v
280 "Type class for parsing strings to values."
282 "Converts a string to a required type of value."
285 The `Additive` class is used for types that are additive monoids. The operations
286 must satisfy the following laws (at least approximately, when implemented for
287 floating point numbers):
288 (a + b) + c = a + (b + c)
291 class Additive a where
293 Neutral element of (+), i.e,
299 "Adds two objects (numbers, vectors, strings, etc.) together."
304 sum [e1,e2,...,eN] = e1 + e2 + ... + eN
306 Implemented usually more efficiently than with repetitive
307 application of `(+)`.
312 class (Additive a) => AdditiveGroup a where
318 The `Ring` class is used for types that are algebraic rings. The operations
319 must satisfy the following laws (at least approximately)
320 in addition to the laws of Additive:
325 (a * b) * c = a * (b * c)
327 a * (b + c) = a * b + a * c
328 (a + b) * c = a * c + b * c
330 class (Additive a) => Ring a where
332 Negation. Synonym for unary `-`.
337 "Neutral element of multiplication"
341 "Converts an integer to a desired numeric type."
342 fromInteger :: Integer -> a
347 The `OrderedRing` class combines the Ring and Ord classes. It additionally
348 supports absolute value function.
350 class (Ring a, Ord a) => OrderedRing a where
353 abs x = if x < zero then neg x else x
354 "Converts the given number to `Integer`"
355 toInteger :: a -> Integer
358 The `Integer` class is used for types that represent either all integers or some
361 class (OrderedRing a) => Integral a where
362 "Integer division truncated toward zero."
364 "Integer remainder, satisfying ``(x `div` y)*y + (x `mod` y) = x``"
368 The `Real` class is used for types that represent some approximation of real numbers.
370 class (OrderedRing a) => Real a where
375 "Pi (3.141592654...)"
401 "Inverse hyberbolic sine"
403 "Inverse hyberbolic cosine"
405 "Inverse hyberbolic tangent"
407 "The largest integer not greater than the given number"
409 "The smallest integer not smaller than the given number"
413 Two parameter version of `atan`. Its value is determined by the following
414 equations when (x,y) is a unit vector:
421 atan2 y x = atan (y/x)
424 "Converts a `Double` value to a desired numeric type."
425 fromDouble :: Double -> a
426 "Converts the given number to `Double`"
427 toDouble :: a -> Double
429 a ^ b = exp (b * log a)
431 sinh x = 0.5 * (exp x - exp (neg x))
432 cosh x = 0.5 * (exp x + exp (neg x))
433 tanh x = (e2x - 1) / (e2x + 1)
437 asinh x = log (x + sqrt (x*x + one))
438 acosh x = log (x + sqrt (x*x - one))
439 atanh x = 0.5 * log ((one+x)/(one-x))
441 /// Import mathematical functions ///
444 importJava "java.lang.Math" where
449 sinDouble :: Double -> Double
452 cosDouble :: Double -> Double
455 tanDouble :: Double -> Double
458 asinDouble :: Double -> Double
461 acosDouble :: Double -> Double
464 atanDouble :: Double -> Double
467 atan2Double :: Double -> Double -> Double
470 sinhDouble :: Double -> Double
473 coshDouble :: Double -> Double
476 tanhDouble :: Double -> Double
479 expDouble :: Double -> Double
482 logDouble :: Double -> Double
485 powDouble :: Double -> Double -> Double
488 sqrtDouble :: Double -> Double
491 ceilDouble :: Double -> Double
494 floorDouble :: Double -> Double
497 roundDouble :: Double -> Long
500 absInteger :: Integer -> Integer
503 absLong :: Long -> Long
506 absFloat :: Float -> Float
509 absDouble :: Double -> Double
512 minInteger :: Integer -> Integer -> Integer
515 minLong :: Long -> Long -> Long
518 minFloat :: Float -> Float -> Float
521 minDouble :: Double -> Double -> Double
524 maxInteger :: Integer -> Integer -> Integer
527 maxLong :: Long -> Long -> Long
530 maxFloat :: Float -> Float -> Float
533 maxDouble :: Double -> Double -> Double
538 importJava "java.lang.Byte" where
540 showByte :: Byte -> String
543 readByte :: String -> Byte
545 instance Ord Byte where
551 instance Additive Byte where
552 zero = Java.i2b Java.iconst_0
555 instance Ring Byte where
558 one = Java.i2b Java.iconst_1
560 fromInteger = Java.i2b
562 instance Show Byte where
564 precedence v = if v >= 0 then 0 else 100
566 instance Read Byte where
571 importJava "java.lang.Short" where
573 showShort :: Short -> String
576 readShort :: String -> Short
578 instance Ord Short where
584 instance Additive Short where
588 instance Ring Short where
593 fromInteger = Java.i2s
595 instance Show Short where
597 precedence v = if v >= 0 then 0 else 100
599 instance Read Short where
605 importJava "java.lang.Integer" where
607 showInteger :: Integer -> String
610 readInteger :: String -> Integer
612 instance Ord Integer where
618 instance Additive Integer where
622 instance Ring Integer where
629 instance OrderedRing Integer where
633 instance Integral Integer where
637 instance Show Integer where
639 precedence v = if v >= 0 then 0 else 100
641 instance Read Integer where
647 importJava "java.lang.Long" where
649 showLong :: Long -> String
652 readLong :: String -> Long
654 instance Ord Long where
660 instance Additive Long where
664 instance Ring Long where
669 fromInteger = Java.i2l
671 instance OrderedRing Long where
675 instance Integral Long where
679 instance Show Long where
681 precedence v = if v >= 0 then 0 else 100
683 instance Read Long where
688 importJava "java.lang.Float" where
691 compareFloat :: Float -> Float -> Integer
695 showFloat :: Float -> String
699 readFloat :: String -> Float
701 "Converts 32-bit floating point number to a 32-bit integer with the same byte level representation."
702 floatToIntBits :: Float -> Integer
704 instance Ord Float where
705 compare = compareFloat
711 instance Additive Float where
715 instance Ring Float where
720 fromInteger = Java.i2f
722 instance OrderedRing Float where
726 instance Real Float where
728 x ^ y = Java.d2f (powDouble (Java.f2d x) (Java.f2d y))
729 pi = fromDouble piDouble
730 sqrt = Java.d2f . sqrtDouble . Java.f2d
731 exp = Java.d2f . expDouble . Java.f2d
732 log = Java.d2f . logDouble . Java.f2d
733 sin = Java.d2f . sinDouble . Java.f2d
734 cos = Java.d2f . cosDouble . Java.f2d
735 tan = Java.d2f . tanDouble . Java.f2d
736 asin = Java.d2f . asinDouble . Java.f2d
737 acos = Java.d2f . acosDouble . Java.f2d
738 atan = Java.d2f . atanDouble . Java.f2d
739 sinh = Java.d2f . sinhDouble . Java.f2d
740 cosh = Java.d2f . coshDouble . Java.f2d
741 tanh = Java.d2f . tanhDouble . Java.f2d
742 floor = Java.d2f . floorDouble . Java.f2d
743 ceil = Java.d2f . ceilDouble . Java.f2d
744 atan2 y x = Java.d2f (atan2Double (Java.f2d y) (Java.f2d x))
745 round = roundDouble . Java.f2d
746 fromDouble = Java.d2f
749 instance Show Float where
751 precedence v = if v >= 0 then 0 else 100
753 instance Read Float where
758 importJava "java.lang.Double" where
761 compareDouble :: Double -> Double -> Integer
765 showDouble :: Double -> String
768 @JavaName parseDouble
769 readDouble :: String -> Double
771 "Converts 64-bit floating point number to a 64-bit integer with the same byte level representation."
772 doubleToLongBits :: Double -> Long
774 isFinite :: Double -> Boolean
775 isNaN :: Double -> Boolean
776 isInfinite :: Double -> Boolean
778 instance Ord Double where
779 compare = compareDouble
785 instance Additive Double where
789 instance Ring Double where
794 fromInteger = Java.i2d
796 instance OrderedRing Double where
800 instance Real Double where
823 instance Show Double where
825 precedence v = if v >= 0 then 0 else 100
827 instance Read Double where
832 importJava "java.lang.Character" where
834 showCharacter :: Character -> String
836 "Returns true, if the given character is a letter."
837 isLetter :: Character -> Boolean
839 "Returns true, if the given character is a digit."
840 isDigit :: Character -> Boolean
842 instance Ord Character where
848 instance Show Character where
849 sb <+ c = sb << "'" << showCharacter c << "'"
851 "Adds a given integer to the character code."
852 addChar :: Character -> Integer -> Character
855 "Subtracts a given integer from the character code."
856 subChar :: Character -> Character -> Integer
862 The `Functor` class is used for types that can be mapped over. Instances of `Functor` should satisfy the following laws:
865 fmap (f . g) == fmap f . fmap g
867 class Functor f where
868 "Lifts a pure function to the given functor."
869 fmap :: (a -> b) -> f a -> f b
871 class CoFunctor f where
872 comap :: (a -> b) -> f b -> f a
876 class (Functor f) => Applicative f where
878 (<*>) :: f (a -> b) -> f a -> f b
879 (*>) :: f a -> f b -> f b
880 (<*) :: f a -> f b -> f a
882 u *> v = pure (const id) <*> u <*> v
883 u <* v = pure const <*> u <*> v
884 fmap f x = pure f <*> x
889 The `Monad` class defines the basic operations over a monad, a concept from a branch of mathematics known as category theory.
890 From the perspective of a SCL programmer, however, it is best to think of a monad as an abstract datatype of actions.
891 SCL's `mdo expressions provide a convenient syntax for writing monadic expressions.
893 Instances of `Monad` should satisfy the following laws:
895 return a >>= k == k a
897 m >>= (\x -> k x >>= h) == (m >>= k) >>= h
898 fmap f xs == xs >>= return . f
900 class (Functor m) => Monad m where
901 "Inject a value into the monadic type."
903 "Sequentially compose two actions, passing any value produced by the first as an argument to the second."
904 (>>=) :: m a -> (a -> m b) -> m b
906 The join function is the conventional monad join operator. It removes one level of monadic
909 For lists, `join` concatenates a list of lists:
911 join [[1,2], [3,4]] = [1, 2, 3, 4]
913 join :: m (m a) -> m a
917 Sequentially compose two actions, discarding any value produced by the first, like sequencing operators
918 (such as the semicolon) in imperative languages."
921 (>>) :: Monad m => m a -> m b -> m b
922 a >> b = a >>= (\_ -> b)
924 "Left-to-right Kleisli composition of monads."
925 (>=>) :: Monad m => (a -> m b) -> (b -> m c) -> (a -> m c)
926 (f >=> g) x = (f x) >>= g
928 "While loop. `while cond body` executes the `body` while the `cond` is true."
930 while :: (<e> Boolean) -> (<e> a) -> <e> ()
931 while cond body = loop ()
932 where loop _ = if cond
933 then do body ; loop ()
937 Sequences the given monadic value infinitely:
939 repeatForever m = m >> m >> m >> ...
941 repeatForever m = m >> repeatForever m
943 replicateM :: Monad m => Integer -> m a -> m [a]
944 replicateM count m = loop count emptyList
946 loop count l | count <= 0 = return l
949 loop (count-1) (addList l v)
951 replicateM_ :: Monad m => Integer -> m a -> m ()
952 replicateM_ count m | count <= 0 = return ()
953 | otherwise = m >> replicateM_ (count-1) m
958 A class of monads with zero element satisfying
962 class (Monad m) => MonadZero m where
965 "Injects a boolean test to a type beloning to `MonadZero`."
966 guard :: MonadZero m => Boolean -> m ()
967 guard True = return ()
973 A class of monads with associative binary operator `mplus` satisfying the following laws:
977 mplus (mplus a b) c = mplus a (mplus b c)
978 mplus a b >>= k = mplus (a >>= k) (b >>= k)
980 class (MonadZero m) => MonadPlus m where
981 mplus :: m a -> m a -> m a
986 A class of monads with associative binary operator `morelse` satisfying the following laws:
990 morelse (morelse a b) c = morelse a (morelse b c)
991 morelse (return a) b = return a
993 class (MonadZero m) => MonadOr m where
994 morelse :: m a -> m a -> m a
999 A class of types that can be mapped over with effectful mapping functions.
1001 class (Functor f) => FunctorE f where
1003 Applies the function to all elements of the container and
1004 returns the similarly shaped container with the results:
1008 map f [e1, e2, ..., eN] = [f e1, f e2, ..., f eN]
1012 map (*2) [1..5] = [2, 4, 6, 8, 10]
1014 map :: (a -> <e> b) -> f a -> <e> (f b)
1015 "Calls the given function with all elements of the given container."
1016 iter :: (a -> <e> b) -> f a -> <e> ()
1017 "Calls the given function with all elements of the given container giving also the index of the element as a parameter."
1018 iterI :: (Integer -> a -> <e> b) -> f a -> <e> ()
1020 "Iterates the elements of the given collection. Same as `iter` but parameters flipped."
1021 for :: FunctorE f => f a -> (a -> <e> b) -> <e> ()
1025 "Iterates the elements of the given collection providing also the indices of the elements. Same as `iterI` but parameters flipped."
1026 forI :: FunctorE f => f a -> (Integer -> a -> <e> b) -> <e> ()
1028 forI l f = iterI f l
1030 "`forN n f` calls `f` for all integers `0`, ..., `n-1`"
1032 forN :: Integer -> (Integer -> <e> b) -> <e> ()
1036 then do f i ; loop (i+1)
1040 mapI :: (Integer -> a -> <e> b) -> [a] -> <e> [b]
1041 mapI f l = build (\empty cons -> let
1043 loop i accum = if i < len
1044 then loop (i+1) (cons accum (f i (l!i)))
1049 `mapMaybe` combines `map` and `filter` functions.
1050 It applies the given function to every element of the input list. If the result
1051 is `Just x`, then `x` is added to the resulting list.
1053 mapMaybe f lst = [y | x <- lst, Just y = f x]
1056 mapMaybe :: (a -> <e> Maybe b) -> [a] -> <e> [b]
1057 mapMaybe f l = build (\empty cons -> foldl (\cur x -> match f x with Just v -> cons cur v ; _ -> cur) empty l)
1060 Applies the given function to all elements of the list. Produces two lists: the first contains all elements `x`
1061 for which the function returned `Left x` and the second list contains all elements `y` for which the function
1064 mapEither :: (a -> <e> Either b c) -> [a] -> <e> ([b], [c])
1065 mapEither f list = runProc do
1068 for list (\x -> match f x with
1069 Left v -> addArrayList l v
1070 Right v -> addArrayList r v)
1071 (Java.unsafeCoerce l, Java.unsafeCoerce r)
1073 "`replicate n v` returns a list of length `n` such that each element is a copy of `v`."
1075 replicate :: Integer -> a -> [a]
1076 replicate n v = build (\empty cons ->
1078 aux i l = aux (i-1) (cons l v)
1084 class (FunctorE f) => FunctorM f where
1085 "`mapM f` is equivalent to `sequence . map f`."
1086 mapM :: Monad m => (a -> <e> m b) -> f a -> <e> m (f b)
1087 "Evaluate each action in the sequence from left to right, and collect the results."
1088 sequence :: Monad m => f (m a) -> m (f a)
1089 mapM f l = sequence (map f l)
1093 class (FunctorE m, Monad m) => MonadE m where
1094 bindE :: m a -> (a -> <e> m b) -> <e> m b
1096 instance MonadE Maybe where
1097 bindE Nothing _ = Nothing
1098 bindE (Just v) f = f v
1100 instance MonadE (Either a) where
1101 bindE (Left v) _ = Left v
1102 bindE (Right v) f = f v
1104 instance MonadE [] where
1105 bindE l f = concatMap f l
1109 "Identity function."
1114 Ignores the given value. This function is used in a situation where a function returns
1115 a value in a context where the value is not expected.
1122 ignoreM :: a -> Maybe b
1126 Composes two functions
1129 (.) :: (b -> <e> c) -> (a -> <e> b) -> (a -> <e> c)
1134 "A type class for sequences. All sequences must support indexing by integers."
1135 class /*(Additive a) =>*/ Sequence a where
1136 "Length of the sequence"
1137 length :: a -> Integer
1138 "`take n s` returns the first `n` elements of the sequence `s`."
1139 take :: Integer -> a -> a
1140 "`drop n s` removes the first `n` elements of the sequence `s`."
1141 drop :: Integer -> a -> a
1143 `sub s begin end` returns a subsequence of `s` starting from
1144 index `begin` and ending just before index `end`.
1146 sub :: a -> Integer -> Integer -> a
1148 take n v = sub v 0 (min n (length v))
1149 drop n v = sub v (min n len) len
1153 instance Sequence [a] where
1157 instance Sequence String where
1158 length = lengthString
1161 class IndexedSequence f where
1162 "`seq ! i` returns the `i`th element of the sequence `seq`. Indexing starts from zero."
1163 (!) :: f a -> Integer -> a
1165 "Returns the first element of a sequence"
1169 "Returns the last element of a sequence"
1171 last l = l!(length l-1)
1173 instance IndexedSequence [] where
1179 Equivalent to the boolean value `True`. The value is meant to be used in
1186 otherwise :: Boolean
1189 instance Ord Boolean where
1190 compare False False = 0
1191 compare False True = neg 1
1192 compare True False = 1
1193 compare True True = 0
1195 instance Show Boolean where
1197 show False = "False"
1200 Boolean conjunction (and). The function is a macro that evaluates the second parameter
1201 only if the first parameter is `True`.
1204 <tr><th>a</th><th>b</th><th>a && b</th></tr>
1205 <tr><td>True</td><td>True</td><td>True</td></tr>
1206 <tr><td>True</td><td>False</td><td>False</td></tr>
1207 <tr><td>False</td><td>not evaluated</td><td>False</td></tr>
1211 (&&) :: Boolean -> Boolean -> Boolean
1212 a && b = if a then b else False
1215 Boolean disjunction (or). The function is a macro that evaluates the second parameter
1216 only if the first parameter is `False`.
1219 <tr><th>a</th><th>b</th><th>a || b</th></tr>
1220 <tr><td>True</td><td>not evaluated</td><td>True</td></tr>
1221 <tr><td>False</td><td>True</td><td>True</td></tr>
1222 <tr><td>False</td><td>False</td><td>False</td></tr>
1226 (||) :: Boolean -> Boolean -> Boolean
1227 a || b = if a then True else b
1231 not a = if a then False else True
1235 //data Maybe a = Nothing | Just a
1237 "Given `Just x` this function returns `x`. If the parameter is `Nothing`, the function raises an exception."
1238 fromJust :: Maybe a -> a
1239 fromJust (Just a) = a
1241 deriving instance (Ord a) => Ord (Maybe a)
1242 deriving instance (Show a) => Show (Maybe a)
1244 instance Functor Maybe where
1245 fmap _ Nothing = Nothing
1246 fmap f (Just x) = Just (f x)
1248 instance FunctorE Maybe where
1249 map _ Nothing = Nothing
1250 map f (Just x) = Just (f x)
1253 iter f (Just x) = ignore (f x)
1255 iterI _ Nothing = ()
1256 iterI f (Just x) = ignore (f 0 x)
1258 instance Monad Maybe where
1262 Nothing >>= _ = Nothing
1266 join Nothing = Nothing
1269 instance MonadZero Maybe where
1272 instance MonadOr Maybe where
1273 morelse a@(Just _) _ = a
1276 "`execJust v f` executes the function `f` with parameter value `x`, if `v=Just x`. If `v=Nothing`, the function does nothing."
1278 execJust :: Maybe a -> (a -> <e> b) -> <e> ()
1279 execJust maybeValue procedure = match maybeValue with
1280 Just v -> ignore $ procedure v
1283 "`fromMaybe def v` returns `def` if `v=Nothing` and `x` if `v=Just x`."
1285 fromMaybe :: a -> Maybe a -> a
1286 fromMaybe default maybeValue = match maybeValue with
1292 Provides a default value if the first parameter is Nothing.
1293 The default value is evaluated only if needed. The function
1294 can be used as an operator and is right associative so that
1295 the following is possible:
1297 tryWithTheFirstMethod
1298 `orElse` tryWithTheSecondMethod
1299 `orElse` fail "Didn't succeed."
1302 orElse :: Maybe a -> (<e> a) -> <e> a
1303 orElse (Just x) _ = x
1304 orElse Nothing def = def
1309 The Either type represents values with two possibilities: a value of type `Either a b` is either `Left a` or `Right b`.
1311 The `Either` type is sometimes used to represent a value which is either correct or an error; by convention, the `Left` constructor
1312 is used to hold an error value and the `Right` constructor is used to hold a correct value (mnemonic: "right" also means "correct").
1314 @JavaType "org.simantics.scl.runtime.either.Either"
1316 @JavaType "org.simantics.scl.runtime.either.Left"
1319 | @JavaType "org.simantics.scl.runtime.either.Right"
1323 deriving instance (Ord a, Ord b) => Ord (Either a b)
1324 deriving instance (Show a, Show b) => Show (Either a b)
1326 instance Functor (Either a) where
1327 fmap _ (Left x) = Left x
1328 fmap f (Right y) = Right (f y)
1330 instance FunctorE (Either a) where
1331 map _ (Left x) = Left x
1332 map f (Right y) = Right (f y)
1334 iter _ (Left x) = ()
1335 iter f (Right y) = ignore (f y)
1337 iterI _ (Left x) = ()
1338 iterI f (Right y) = ignore (f 0 y)
1340 instance Monad (Either b) where
1343 Left x >>= _ = Left x
1346 join (Left x) = Left x
1351 importJava "java.lang.String" where
1354 concatString :: String -> String -> String
1356 @JavaName "compareTo"
1357 compareString :: String -> String -> Integer
1360 lengthString :: String -> Integer
1363 `replaceString original pattern replacement` replaces all occurrences of `pattern` in the string by `replacement`.
1366 replaceString :: String -> String -> String -> String
1370 splitString_ :: String -> String -> Array String
1373 `indexOf string s` finds the first occurrence of `s` from `string` and returns its index.
1374 If the `s` does not occur in the string, return `-1`."
1377 indexOf :: String -> String -> Integer
1379 "Works like `indexOf` but starts searching from the given index instead of the beginning of the string."
1381 indexOfStartingFrom :: String -> String -> Integer -> Integer
1383 "Works like `indexOf` but returns the index of the last occurrence."
1384 @JavaName lastIndexOf
1385 lastIndexOf :: String -> String -> Integer
1387 "Works like `lastIndexOf` but starts searching from the given index instead of the end of the string."
1388 @JavaName lastIndexOf
1389 lastIndexOfStartingFrom :: String -> String -> Integer -> Integer
1393 subString :: String -> Integer -> Integer -> String
1396 `regionMatches str1 offset1 str2 offset2 len` tests whether
1397 `sub str1 offset1 (offset1+len) == sub str2 offset2 (offset2+len)`.
1399 regionMatches :: String -> Integer -> String -> Integer -> Integer -> Boolean
1401 "`startsWith string prefix` returns true if the string begins with the given prefix."
1402 startsWith :: String -> String -> Boolean
1404 "`endsWith string suffix` returns true if the string ends with the given prefix."
1405 endsWith :: String -> String -> Boolean
1407 "Removes leading and trailing whitespace from the string."
1408 trim :: String -> String
1410 "`contains string s` returns true if `string` contains `s` as a substring."
1411 contains :: String -> String -> Boolean
1413 "`charAt string i` returns the `i`th character of the string."
1414 charAt :: String -> Integer -> Character
1416 "Converts all letters of the string to lower case."
1417 toLowerCase :: String -> String
1418 "Converts all letters of the string to upper case."
1419 toUpperCase :: String -> String
1421 "Creates a string from a vector of characters."
1423 string :: Vector Character -> String
1425 getBytes :: String -> String -> ByteArray
1427 getBytesUTF8 :: String -> ByteArray
1428 getBytesUTF8 str = getBytes str "UTF-8"
1430 instance Ord String where
1431 compare = compareString
1433 instance Additive String where
1436 sum ss = runProc (StringBuilder.toString $ foldl StringBuilder.appendString StringBuilder.new ss)
1439 importJava "org.simantics.scl.runtime.string.StringEscape" where
1440 appendEscapedString :: StringBuilder.T -> String -> <Proc> StringBuilder.T
1442 instance Show String where
1443 showForPrinting = id
1444 sb <+ v = (appendEscapedString (sb << "\"") v) << "\""
1446 instance Read String where
1449 @deprecated "Instead of 'splitString text pattern', write 'split pattern text' (note change in the parameter order)."
1450 "`splitString text pattern` splits the string into a list of string where the parts are sepratated in the original list by the given pattern."
1451 splitString :: String -> String -> [String]
1452 splitString source pattern = arrayToList $ splitString_ source pattern
1455 `split pattern text` splits `text` around matches of the given regular expression `pattern`.
1457 This function works as if by invoking the two-argument split method with the given expression and a limit argument of zero. Trailing empty strings are therefore not included in the resulting array.
1459 The string "boo:and:foo", for example, yields the following results with these expressions:
1462 : { "boo", "and", "foo" }
1463 o { "b", "", ":and:f" }
1465 split :: String -> String -> [String]
1466 split pattern text = arrayToList $ splitString_ text pattern
1470 instance Ord () where
1473 instance Additive () where
1477 instance Show () where
1482 "Gives the first element of a pair."
1487 "Gives the second element of a pair."
1493 mapFst :: (a -> b) -> (a,c) -> (b,c)
1494 mapFst f (x,y) = (f x, y)
1497 mapSnd :: (a -> b) -> (c,a) -> (c,b)
1498 mapSnd f (x,y) = (x, f y)
1500 instance (Ord a, Ord b) => Ord (a, b) where
1501 compare (a0, b0) (a1, b1) = compare a0 a1 &<& compare b0 b1
1503 instance (Additive a, Additive b) => Additive (a, b) where
1505 (a0, b0) + (a1, b1) = (a0+a1, b0+b1)
1507 instance Functor ((,) a) where
1508 fmap f (a,b) = (a, f b)
1510 instance (Show a, Show b) => Show (a, b) where
1511 sb <+ (x, y) = sb << "(" <+ x << ", " <+ y << ")"
1515 instance (Ord a, Ord b, Ord c) => Ord (a, b, c) where
1516 compare (a0, b0, c0) (a1, b1, c1) = compare a0 a1 &<& compare b0 b1 &<& compare c0 c1
1518 instance (Additive a, Additive b, Additive c) => Additive (a, b, c) where
1519 zero = (zero, zero, zero)
1520 (a0, b0, c0) + (a1, b1, c1) = (a0+a1, b0+b1, c0+c1)
1522 instance Functor ((,,) a b) where
1523 fmap f (a,b,c) = (a, b, f c)
1525 instance (Show a, Show b, Show c) => Show (a, b, c) where
1526 sb <+ (x, y, z) = sb << "(" <+ x << ", " <+ y << ", " <+ z << ")"
1530 instance (Ord a, Ord b, Ord c, Ord d) => Ord (a, b, c, d) where
1531 compare (a0, b0, c0, d0) (a1, b1, c1, d1) =
1532 compare a0 a1 &<& compare b0 b1 &<& compare c0 c1 &<& compare d0 d1
1534 instance (Additive a, Additive b, Additive c, Additive d) => Additive (a, b, c, d) where
1535 zero = (zero, zero, zero, zero)
1536 (a0, b0, c0, d0) + (a1, b1, c1, d1) = (a0+a1, b0+b1, c0+c1, d0+d1)
1538 instance Functor ((,,,) a b c) where
1539 fmap f (a,b,c,d) = (a, b, c, f d)
1541 instance (Show a, Show b, Show c, Show d) => Show (a, b, c, d) where
1542 sb <+ (x, y, z, w) = sb << "(" <+ x << ", " <+ y << ", " <+ z << ", " <+ w << ")"
1546 instance (Ord a, Ord b, Ord c, Ord d, Ord e) => Ord (a, b, c, d, e) where
1547 compare (a0, b0, c0, d0, e0) (a1, b1, c1, d1, e1) =
1548 compare a0 a1 &<& compare b0 b1 &<& compare c0 c1 &<& compare d0 d1 &<& compare e0 e1
1550 instance (Additive a, Additive b, Additive c, Additive d, Additive e) => Additive (a, b, c, d, e) where
1551 zero = (zero, zero, zero, zero, zero)
1552 (a0, b0, c0, d0, e0) + (a1, b1, c1, d1, e1) = (a0+a1, b0+b1, c0+c1, d0+d1, e0+e1)
1554 instance Functor ((,,,,) a b c d) where
1555 fmap f (a,b,c,d,e) = (a, b, c, d, f e)
1559 instance (Ord a) => Ord [a] where
1560 compare a b = loop 0
1565 then (if i >= lB then 0 else -1)
1568 else compare (a!i) (b!i) &<& loop (i+1)
1570 instance Functor [] where
1573 instance FunctorE [] where
1578 instance Monad [] where
1579 return x = singletonList x
1580 l >>= f = concatMap f l
1583 instance MonadZero [] where
1586 instance MonadPlus [] where
1589 instance Additive [a] where
1593 instance FunctorM [] where
1594 sequence = foldl (\m mel -> m >>= \l -> mel >>= \el -> return (addList l el)) (return emptyList)
1595 mapM f l = sequence (map f l)
1597 "Appends the string representations of all elements of the list to the string builder and separates the values with the given separator."
1598 printWithSeparator :: Show a => StringBuilder.T -> String -> [a] -> <Proc> StringBuilder.T
1599 printWithSeparator sb sep l = loop 0
1602 loop i = if i >= len then sb
1604 (if i==0 then sb else sb << sep) <+ l!i
1608 Joins the string representations of the list of values with the given separator.
1610 See [intercalate](#intercalate) for an alternative that works with Strings
1611 and doesn't escape its arguments.
1613 joinWithSeparator :: Show a => String -> [a] -> String
1614 joinWithSeparator separator values = runProc (
1615 StringBuilder.toString $ printWithSeparator StringBuilder.new separator values)
1619 The intercalate function takes a String and a list of Strings
1620 and concatenates the list after interspersing the first argument
1621 between each element of the list.
1623 See also more generic [joinWithSeparator](#joinWithSeparator)
1624 which escapes its arguments using `show`.
1626 intercalate :: String -> [String] -> String
1627 intercalate separator strings = do
1634 sb = StringBuilder.new
1636 loop i | i == l = ()
1638 sb << separator << strings!i
1641 StringBuilder.toString sb
1643 instance (Show a) => Show [a] where
1648 if (i>0) then sb << ", " else sb
1655 importJava "java.util.List" where
1656 "`getList l i` returns the `i`th element of the list `l`. Indexing starts from zero. You can also use the `!` infix function for this purpose."
1658 getList :: [a] -> Integer -> a
1662 lengthList :: [a] -> Integer
1665 subList :: [a] -> Integer -> Integer -> [a]
1668 isEmpty :: [a] -> Boolean
1671 importJava "java.util.Collections" where
1673 //singletonList :: a -> [a]
1678 emptyList = build (\empty cons -> empty)
1681 "Creates a list with exectly one element."
1683 singletonList :: a -> [a]
1684 singletonList v = build (\empty cons -> cons empty v)
1687 // foldl f i (a + b) = foldl f (foldl f i a) b
1689 appendList :: [a] -> [a] -> [a]
1690 appendList a b = build (\empty cons -> foldl cons (foldl cons empty a) b)
1693 importJava "org.simantics.scl.runtime.list.ShareableList" where
1694 "Concatenates two lists."
1697 appendList :: [a] -> [a] -> [a]
1699 "Adds the given value to the end of the list."
1701 addList :: [a] -> a -> [a]
1704 importJava "java.util.ArrayList" where
1708 newArrayList :: <Proc> ArrayList a
1711 addArrayList :: ArrayList a -> a -> <Proc> ()
1714 A primitive for constructing a list by `empty` and `cons` operations given to the function given as a parameter to this function.
1717 build (\empty cons -> cons (cons (cons empty 1) 2) 3)
1723 The SCL compiler makes the following optimization when encountering `build` and `foldl` functions after inlining:
1725 foldl f i (build g) = g i f
1728 build :: forall b e2. (forall a e1. a -> (a -> b -> <e1> a) -> <e1,e2> a) -> <e2> [b]
1729 build f = runProc do
1731 f () (\_ v -> addArrayList l v)
1734 "A specific implementation of `map` for lists."
1737 mapEList :: (a -> <e> b) -> [a] -> <e> [b]
1738 mapEList f l = build (\empty cons -> foldl (\cur x -> cons cur (f x)) empty l)
1740 "A specific implementation of `fmap` for lists."
1742 mapList :: (a -> b) -> [a] -> [b]
1743 mapList f l = build (\empty cons -> foldl (\cur x -> cons cur (f x)) empty l)
1745 "`guardList v` returns a singleton `[()]` if `v=True` and the empty list if `v=False`."
1747 guardList :: Boolean -> [()]
1748 guardList cond = build (\empty cons -> if cond then cons empty () else empty)
1751 `concatMap` combines `map` and `join` functions.
1752 It maps the elements of a given list to lists with the given function and concatenates the results.
1754 concatMap f lst = join (map f lst) = [y | x <- lst, y <- f x]
1757 concatMap :: (a -> <e> [b]) -> [a] -> <e> [b]
1758 concatMap f l = build (\empty cons -> foldl (\cur le -> foldl cons cur (f le)) empty l)
1761 Applies the given function to the elements of the lists until the function returns something
1762 else than `Nothing`. This return value is also returned as a result of this function.
1765 mapFirst :: (a -> <e> Maybe b) -> [a] -> <e> Maybe b
1766 mapFirst f l = loop 0
1769 loop i = if i == len
1771 else match f (l!i) with
1773 Nothing -> loop (i+1)
1776 foldl op initialValue list
1778 applies a binary operator `op` to all elements of `list` from left to right
1779 starting with `initialValue`. For example,
1781 foldl op init [x1, x2, x3, x4] = (((init `op` x1) `op` x2) `op` x3) `op` x4
1784 foldl :: forall a b e. (a -> b -> <e> a) -> a -> [b] -> <e> a
1785 foldl f initial l = loop initial 0
1788 loop cur i = if i==len
1790 else loop (f cur (l!i)) (i+1)
1792 foldlI :: forall a b e. (Integer -> a -> b -> <e> a) -> a -> [b] -> <e> a
1793 foldlI f initial l = loop initial 0
1796 loop cur i = if i==len
1798 else loop (f i cur (l!i)) (i+1)
1800 scanl :: (b -> a -> <e> b) -> b -> [a] -> <e> [b]
1801 scanl f initial l = build (\empty cons -> let
1803 loop cur i accum = let nl = cons accum cur
1806 else loop (f cur (l!i)) (i+1) nl
1807 in loop initial 0 empty)
1809 "`foldr` is defined like `foldl` but it process the list from right to left."
1811 foldr :: (b -> a -> <e> a) -> a -> [b] -> <e> a
1812 foldr f initial l = loop initial (length l - 1)
1814 loop cur i = if i < 0
1816 else loop (f (l!i) cur) (i-1)
1818 foldr1 :: (a -> a -> <e> a) -> [a] -> <e> a
1819 foldr1 f l = loop (l!(len-1)) (len-2)
1822 loop cur i = if i < 0
1824 else loop (f (l!i) cur) (i-1)
1827 `filter pred lst` returns those elements of `lst` that the predicate `pred` accepts. For example
1829 filter (> 3) [1, 2, 3, 4, 5, 6] = [4, 5, 6]
1832 filter :: (a -> <e> Boolean) -> [a] -> <e> [a]
1833 filter p l = build (\empty cons -> foldl (\cur x -> if p x then cons cur x else cur) empty l)
1836 Takes those elements of the input list that match `(Just x)` and adds the contents to the resulting list. For example,
1838 filterJust [Just 1, Nothing, Just 5] = [1, 5]
1841 filterJust :: [Maybe a] -> [a]
1842 filterJust l = build (\empty cons -> foldl (\cur x -> match x with Just v -> cons cur v ; _ -> cur) empty l)
1844 listToMaybe :: [a] -> Maybe a
1845 listToMaybe l = if isEmpty l then Nothing else Just (l!0)
1847 maybeToList :: Maybe a -> [a]
1848 maybeToList (Just a) = [a]
1852 `takeWhile p l`, returns the longest prefix (possibly empty) of list `l` of elements that satisfy `p`
1854 takeWhile :: (a -> <e> Boolean) -> [a] -> <e> [a]
1855 takeWhile f l = loop 0
1858 loop i | i == len = l
1859 | f (l!i) = loop (i+1)
1860 | otherwise = take i l
1862 partition :: (a -> <e> Boolean) -> [a] -> <e> ([a], [a])
1863 partition p l = runProc do
1868 then addArrayList res1 el
1869 else addArrayList res2 el
1871 (Java.unsafeCoerce res1, Java.unsafeCoerce res2)
1874 `range begin end` produces a list of consecutive integers starting from `begin` and ending to `end` (including `end`).
1875 The compiler supports syntactic sugar `[begin..end]` for this function.
1878 range :: Integer -> Integer -> [Integer]
1879 range first last = build (\empty cons -> do
1880 loop i cur = if i > last then cur else loop (i+1) (cons cur i)
1883 "A specific implementation of `iter` for lists."
1885 iterList :: (a -> <e> b) -> [a] -> <e> ()
1886 iterList f l = foldl (\_ x -> ignore (f x)) () l
1888 "A specific implementation of `iterI` for lists."
1890 iterIList :: (Integer -> a -> <e> b) -> [a] -> <e> ()
1891 iterIList f l = do foldl (\i x -> do f i x ; i+1) 0 l ; ()
1894 Generates a list from a given starting state and iteration function.
1897 let nextState 0 = Nothing
1898 nextState i = Just (i, i `div` 2)
1899 in unfoldr nextState 30
1906 unfoldr :: (b -> <e> Maybe (a, b)) -> b -> <e> [a]
1907 unfoldr f s = build (\empty cons -> do
1910 Just (el,newS) -> loop newS (cons cur el)
1914 importJava "org.simantics.scl.runtime.Lists" where
1918 mapList :: (a -> b) -> [a] -> [b]
1921 mapEList :: (a -> <e> b) -> [a] -> <e> [b]
1924 iterList :: (a -> <e> ()) -> [a] -> <e> ()
1925 concatMap :: (a -> <e> [b]) -> [a] -> <e> [b]
1928 Combines two lists into one list of pairs. The length of the resulting list is the length of the smallest input list.
1930 zip [1, 2, 3, 4, 5] ['a', 'b', 'c'] = [(1, 'a'), (2, 'b'), (3, 'c')]
1932 zip :: [a] -> [b] -> [(a,b)]
1933 "Combines two lists by using the given function for combining the elements. The length of the resulting list is the length of the smallest input list."
1934 zipWith :: (a -> b -> <e> c) -> [a] -> [b] -> <e> [c]
1936 Produces two lists from one list of pairs.
1938 unzip [(1, 'a'), (2, 'b'), (3, 'c')] = ([1, 2, 3], ['a', 'b', 'c'])
1940 unzip :: [(a,b)] -> ([a],[b])
1942 //"@filter p l@ returns those elements of @l@ that the predicate @p@ accepts."
1943 //filter :: (a -> <e> Boolean) -> [a] -> <e> [a]
1944 //filterJust :: [Maybe a] -> [a]
1946 foldl :: (a -> b -> <e> a) -> a -> [b] -> <e> a
1948 "Like `foldl` but assumes that the list is non-empty so the initial is not needed."
1949 foldl1 :: (a -> a -> <e> a) -> [a] -> <e> a
1950 //unfoldr :: (b -> <e> Maybe (a, b)) -> b -> <e> [a]
1952 "Sorts the list using the given comparator."
1953 sortWith :: (a -> a -> <e> Integer) -> [a] -> <e> [a]
1956 Given a list of key-value pairs, the function produces a function that finds a value
1957 efficiently for the given key.
1959 index :: [(a,b)] -> a -> Maybe b
1962 Given a list of values and a function computing a key for each value, the function produces a function that finds a value
1963 effeciently for the given key.
1965 indexBy :: (a -> <e> b) -> [a] -> <e> (b -> Maybe a)
1967 "Works like `index` but uses the given functions as hash codes and equality."
1968 indexWith :: (a -> Integer) -> (a -> a -> Boolean) -> [(a,b)] -> a -> Maybe b
1970 "Groups a list values by a key computed by the given function."
1971 groupBy :: (a -> <e> b) -> [a] -> <e> [(b, [a])]
1973 "Groups a list of key-value pairs by the keys."
1974 group :: [(a,b)] -> [(a, [b])]
1976 "Composition of index and groupBy."
1977 indexGroupBy :: (a -> <e> b) -> [a] -> <e> (b -> [a])
1979 "Composition of index and group."
1980 indexGroup :: [(a,b)] -> a -> [b]
1982 groupWith :: (b -> Integer) -> (b -> b -> Boolean) -> (a -> <e> b) -> (a -> <e> c) -> [a] -> <e> [(b, [c])]
1984 "Removes duplicates (all but the first occurrence) from the list but otherwise preserves the order of the elements."
1985 unique :: [a] -> [a]
1987 "Like `unique`, but uses the given function for finding the key values used for uniqueness testing."
1988 uniqueBy :: (a -> b) -> [a] -> [a]
1990 "Works like `unique` but uses the given function for equality tests."
1991 uniqueWith :: (a -> a -> Boolean) -> [a] -> [a]
1993 "Works like `\\\\` but uses the given function for equality tests."
1994 deleteAllBy :: (a -> a -> Boolean) -> [a] -> [a] -> [a]
1997 listDifference :: [a] -> [a] -> [a]
1999 //range :: Integer -> Integer -> [Integer]
2001 //build :: (forall a. a -> (a -> b -> <e> a) -> <e> a) -> <e> [b]
2003 "`elem el lst` return true, if `el` occurs in the list `lst`."
2004 elem :: a -> [a] -> Boolean
2008 loop i | i < len = if el == l!i
2013 "`elemMaybe v1 (Just v2)` returns true if `v1 == v2`. `elemMaybe v1 Nothing` is always false."
2014 elemMaybe :: a -> Maybe a -> Boolean
2015 elemMaybe el m = match m with
2016 Just el2 -> el == el2
2019 "`elemIndex el lst` returns the index of the first element in the given list `lst` which is equal (by ==) to the query element, or Nothing if there is no such element."
2020 elemIndex :: a -> [a] -> Maybe Integer
2021 elemIndex el l = loop 0
2024 loop i | i < len = if el == l!i
2027 | otherwise = Nothing
2030 Computes a list that contains only elements that belongs to both input lists.
2032 intersect :: [a] -> [a] -> [a]
2033 intersect a b = filter f a
2037 "Reverses a given list. For example, `reverse [1,2,3] = [3,2,1]`"
2038 reverse :: [a] -> [a]
2039 reverse l = [l!(len-i) | i <- [1..len]]
2044 Transposes the rows and columns of its argument. For example,
2046 transpose [[1,2,3],[4,5,6]] == [[1,4],[2,5],[3,6]]
2047 transpose [[1,2],[3,4,5]] == [[1,3],[2,4],[5]]
2049 transpose xss = [[xs!i | xs <- xss, i < length xs]
2050 | i <- [0..maximum [length xs | xs <- xss]-1]]
2052 "Works like `unfoldr` but generates the list from right to left."
2053 unfoldl :: (b -> <e> Maybe (a, b)) -> b -> <e> [a]
2054 unfoldl f seed = reverse $ unfoldr f seed
2056 "Removes the first element of the list, if the list is non-empty."
2058 tail l = if len < 2 then emptyList else subList l 1 len
2062 "Tries to find the given key from the list of key-value pairs and returns the corresponding value."
2063 lookup :: a -> [(a, b)] -> Maybe b
2068 (a,b) | a == el -> Just b
2069 | otherwise -> loop (i+1)
2073 "Conjunction over a list."
2075 and :: [Boolean] -> Boolean
2076 and = foldl (&&) True
2078 "Disjunction over a list."
2080 or :: [Boolean] -> Boolean
2081 or = foldl (||) False
2084 `any pred lst` tests whether the predicate `pred` holds some element of `lst`.
2085 It returns immediately when it encounters the first value satisfying the predicate.
2087 any :: (a -> <e> Boolean) -> [a] -> <e> Boolean
2091 `all pred lst` tests whether the predicate `pred` holds for all elements of `lst`.
2092 It returns immediately when it encounters the first value not satisfying the predicate.
2094 all :: (a -> <e> Boolean) -> [a] -> <e> Boolean
2098 Returns the first element of the list satisfying the given condition,
2099 or `Nothing` if there is no such element.
2101 findFirst :: (a -> <e> Boolean) -> [a] -> <e> Maybe a
2102 findFirst p l = loop 0
2106 then let el = l!i in
2115 Sorts the given list using its default order.
2118 sort :: Ord a => [a] -> [a]
2119 sort = sortWith compare
2122 Sorts the lists by the values computed by the first function.
2125 sortBy snd [(1,5), (2,3), (3,4)] = [(2,3), (3,4), (1,5)]
2128 sortBy :: Ord b => (a -> <e> b) -> [a] -> <e> [a]
2129 sortBy f l = sortWith (\x y -> compare (f x) (f y)) l
2130 // This is faster if f is slow, but will generate more auxiliary structures
2131 //sortBy f l = map snd (sortWith (\(x,_) (y,_) -> compare x y) [(f x, x) | x <- l])
2133 "`a \\\\ b` removes all elements of `b` from the list `a`."
2134 (\\) :: [a] -> [a] -> [a]
2135 (\\) = listDifference
2139 importJava "java.lang.Object" where
2140 "A data type that can represent any value."
2145 showDynamic :: Dynamic -> String
2147 instance Show Dynamic where
2150 "Converts a value to `Dynamic` type."
2151 toDynamic :: a -> Dynamic
2152 toDynamic = Java.unsafeCoerce
2154 "Converts a `Dynamic` value to a required value, or fails if the conversion is not possible."
2155 importJava "org.simantics.scl.compiler.runtime.ValueConversion" where
2156 fromDynamic :: Typeable a => Dynamic -> a
2160 importJava "org.simantics.scl.runtime.procedure.Ref" where
2161 "A mutable reference to a value of type `a`."
2164 "Creates a new reference with the given initial value."
2166 ref :: a -> <Proc> (Ref a)
2168 "Returns the current value of the reference."
2170 getRef :: Ref a -> <Proc> a
2172 "Sets a new value for the reference."
2173 @JavaName "<set>value"
2174 (:=) :: Ref a -> a -> <Proc> ()
2176 instance Show (Ref a) where
2177 show _ = "<reference>"
2179 importJava "org.simantics.scl.runtime.reporting.SCLReporting" where
2180 "Prints the given string to the console."
2182 printString :: String -> <Proc> ()
2183 "Prints an error message to the console."
2184 printError :: String -> <Proc> ()
2185 "Reports that certain amount of work has been done for the current task."
2186 didWork :: Double -> <Proc> ()
2188 `printingToFile "fileName" expression` executes the `expression` so that all its console prints
2189 are written to the file given as a first parameter.
2191 printingToFile :: String -> (<e> a) -> <e> a
2193 `printErrorsAsNormalPrints expression` executes the `expression` so that all its error prints
2194 are printed as normal prints. This is useful mainly in testing scripts for checking that the implementations
2195 give proper error messages with invalid inputs.
2197 printErrorsAsNormalPrints :: (<e> a) -> <e> a
2199 `disablePrintingForCommand expression` executes the `expression` so that it does not print return values.
2200 Errors are printed normally.
2202 disablePrintingForCommand :: (<e> a) -> <e> a
2205 importJava "org.simantics.scl.runtime.procedure.Procedures" where
2206 "Returns `True` if the current thread has been interrupted."
2207 isInterrupted :: <Proc> Boolean
2208 "Checks whether the current thread has been interrupted and throws an exception if it is."
2209 checkInterrupted :: <Proc> ()
2210 "Generates a random identifier."
2211 generateUID :: <Proc> String
2213 "Executes the given expression and catches certain class of exceptions (specified by the catch handler that is given as a second parameter.)"
2215 catch :: VecComp ex => (<e,Exception> a) -> (ex -> <e> a) -> <e> a
2217 importJava "java.lang.Throwable" where
2221 showThrowable :: Throwable -> String
2223 @JavaName getMessage
2224 getMessageThrowable :: Throwable -> String
2227 getCauseThrowable :: Throwable -> Maybe Throwable
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 class Throwable e where
2240 toThrowable :: e -> Throwable
2242 messageOfException :: Throwable e => e -> String
2243 messageOfException = getMessageThrowable . toThrowable
2245 causeOfException :: Throwable e => e -> Maybe Throwable
2246 causeOfException = getCauseThrowable . toThrowable
2248 instance Throwable Throwable where
2250 instance Throwable Exception where
2251 toThrowable = Java.unsafeCoerce
2253 "Prints the given value in the console."
2255 print :: Show a => a -> <Proc> ()
2256 print v = printString (showForPrinting v)
2258 instance Show TypeRep where
2259 sb <+ (TApply (TCon "Builtin" "[]") b) =
2260 sb << "[" <+ b << "]"
2261 sb <+ (TApply (TApply (TCon "Builtin" "(,)") c1) c2) =
2262 sb << "(" <+ c1 << "," <+ c2 << ")"
2263 sb <+ (TApply (TApply (TApply (TCon "Builtin" "(,,)") c1) c2) c3) =
2264 sb << "(" <+ c1 << "," <+ c2 << "," <+ c3 << ")"
2265 sb <+ (TApply (TApply (TApply (TApply (TCon "Builtin" "(,,,)") c1) c2) c3) c4) =
2266 sb << "(" <+ c1 << "," <+ c2 << "," <+ c3 << "," <+ c4 << ")"
2268 sb <+ (TCon _ name) = sb << name
2269 sb <+ (TApply a b) = sb <+ Par 1 a << " " <+ Par 2 b
2270 sb <+ (TFun a b) = sb <+ Par 1 a << " -> " <+ b
2272 precedence (TCon _ _) = 0
2273 precedence (TFun _ _) = 2
2274 precedence (TApply a _) = if isSpecialType a then 0 else 1
2276 isSpecialType (TCon "Builtin" "[]") = True
2277 isSpecialType (TCon "Builtin" "()") = True
2278 isSpecialType (TCon "Builtin" "(,)") = True
2279 isSpecialType (TCon "Builtin" "(,,)") = True
2280 isSpecialType (TCon "Builtin" "(,,,)") = True
2281 isSpecialType (TApply a _) = isSpecialType a
2286 importJava "java.util.Arrays" where
2289 byteArrayToString :: ByteArray -> String
2291 instance Show ByteArray where
2292 show = byteArrayToString
2297 importJava "org.simantics.scl.compiler.types.Type" where
2299 showType :: Type -> String
2301 importJava "org.simantics.scl.compiler.types.Types" where
2302 removeForAll :: Type -> Type
2304 instance Show Type where