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 swap :: (a,b) -> (b,a)
132 (!=) :: a -> a -> Boolean
133 a != b = not (a == b)
136 The class of linearly ordered types.
137 Method `compare` must be implemented in instances.
141 `compare x y` returns a negative number, if `x` is smaller than `y`,
142 a positive number, if `x` is bigger than `y` and zero if they are equal.
144 compare :: a -> a -> Integer
145 compare a b = if a < b then -1 else if a > b then 1 else 0
148 (<) :: a -> a -> Boolean
149 a < b = compare a b < 0
151 (<=) :: a -> a -> Boolean
152 a <= b = compare a b <= 0
154 (>) :: a -> a -> Boolean
155 a > b = compare a b > 0
157 (>=) :: a -> a -> Boolean
158 a >= b = compare a b >= 0
160 "Minimum of the parameters"
162 min a b = if a < b then a else b
163 "Maximum of the parameters"
165 max a b = if a > b then a else b
168 Combines two integers such that if the first one is non-zero, it is returned, otherwise
169 the second-one. The second parameter is not implemented, if it is not needed.
171 The function is useful for implementing efficient recursive comparison of structures,
174 compare (x1,y1,z1) (x2,y2,z2) = compare x1 x2 &<& compare y1 y2 &<& compare z1 z2
177 (&<&) :: Integer -> (<e> Integer) -> <e> Integer
178 a &<& b = if a == 0 then b else a
180 "Maximum over a list"
182 maximum :: Ord a => [a] -> a
185 "Minimum over a list"
187 minimum :: Ord a => [a] -> a
190 "As `maximum` but compares the elements by the given projection."
191 maximumBy :: Ord b => (a -> <e> b) -> [a] -> <e> a
192 maximumBy f l = snd $ foldl1 maxF $ map (\x -> (f x, x)) l
194 maxF a b = if fst a >= fst b then a else b
197 As `minimum` but compares the elements by the given projection.
202 returns a pair with the smallest second component.
204 minimumBy :: Ord b => (a -> <e> b) -> [a] -> <e> a
205 minimumBy f l = snd $ foldl1 minF $ map (\x -> (f x, x)) l
207 minF a b = if fst a <= fst b then a else b
211 instance Functor ((->) a) where
214 instance Monad ((->) a) where
216 (m >>= f) x = f (m x) x
219 instance Category (->) where
224 instance (Additive b) => Additive (a -> <e> b) where
226 (f + g) x = f x + g x
228 instance (Ring b) => Ring (a -> <e> b) where
230 (neg f) x = neg (f x)
231 (f - g) x = f x - g x
232 (f * g) x = f x * g x
233 (fromInteger c) x = fromInteger c
235 //instance Show (a -> <e> b) where
236 // show f = "<function>"
238 "Appends a string to the string builder."
239 (<<) :: StringBuilder.T -> String -> <Proc> StringBuilder.T
240 (<<) = StringBuilder.appendString
243 The class of types whose elements can be converted to a string representation.
244 Method `show` or `(<+)` must be implemented.
247 "Converts a value to string."
249 "Appends the string representation of the value to the string builder."
250 (<+) :: StringBuilder.T -> a -> <Proc> StringBuilder.T
252 Returns the precedence of the value. It is used to determine if parenteheses
253 are needed around the string representation of the value. The default value is 0
254 and means that parentheses are never added.
256 precedence :: a -> Integer
258 "Converts a value to a string like `show` but does not put string literals in double quotes."
259 showForPrinting :: a -> String
261 show v = runProc (StringBuilder.toString (StringBuilder.new <+ v))
262 showForPrinting v = show v
263 sb <+ v = StringBuilder.appendString sb (show v)
267 `Par` data type is used to control the placement of parentheses when converting values to string.
268 Value `Par prec val` is converted to string like `val` but parentheses are put around, if the
269 precedence of the value is greater than `prec`.
271 data Par a = Par Integer a
273 instance (Show a) => Show (Par a) where
274 sb <+ (Par outerPrec v) = if prec > outerPrec
275 then sb << "(" <+ v << ")"
277 where prec = precedence v
279 "Type class for parsing strings to values."
281 "Converts a string to a required type of value."
284 The `Additive` class is used for types that are additive monoids. The operations
285 must satisfy the following laws (at least approximately, when implemented for
286 floating point numbers):
287 (a + b) + c = a + (b + c)
290 class Additive a where
292 Neutral element of (+), i.e,
298 "Adds two objects (numbers, vectors, strings, etc.) together."
303 sum [e1,e2,...,eN] = e1 + e2 + ... + eN
305 Implemented usually more efficiently than with repetitive
306 application of `(+)`.
311 class (Additive a) => AdditiveGroup a where
317 The `Ring` class is used for types that are algebraic rings. The operations
318 must satisfy the following laws (at least approximately)
319 in addition to the laws of Additive:
324 (a * b) * c = a * (b * c)
326 a * (b + c) = a * b + a * c
327 (a + b) * c = a * c + b * c
329 class (Additive a) => Ring a where
331 Negation. Synonym for unary `-`.
336 "Neutral element of multiplication"
340 "Converts an integer to a desired numeric type."
341 fromInteger :: Integer -> a
346 The `OrderedRing` class combines the Ring and Ord classes. It additionally
347 supports absolute value function.
349 class (Ring a, Ord a) => OrderedRing a where
352 abs x = if x < zero then neg x else x
353 "Converts the given number to `Integer`"
354 toInteger :: a -> Integer
357 The `Integer` class is used for types that represent either all integers or some
360 class (OrderedRing a) => Integral a where
361 "Integer division truncated toward zero."
363 "Integer remainder, satisfying ``(x `div` y)*y + (x `mod` y) = x``"
367 The `Real` class is used for types that represent some approximation of real numbers.
369 class (OrderedRing a) => Real a where
374 "Pi (3.141592654...)"
400 "Inverse hyberbolic sine"
402 "Inverse hyberbolic cosine"
404 "Inverse hyberbolic tangent"
406 "The largest integer not greater than the given number"
408 "The smallest integer not smaller than the given number"
412 Two parameter version of `atan`. Its value is determined by the following
413 equations when (x,y) is a unit vector:
420 atan2 y x = atan (y/x)
423 "Converts a `Double` value to a desired numeric type."
424 fromDouble :: Double -> a
425 "Converts the given number to `Double`"
426 toDouble :: a -> Double
428 a ^ b = exp (b * log a)
430 sinh x = 0.5 * (exp x - exp (neg x))
431 cosh x = 0.5 * (exp x + exp (neg x))
432 tanh x = (e2x - 1) / (e2x + 1)
436 asinh x = log (x + sqrt (x*x + one))
437 acosh x = log (x + sqrt (x*x - one))
438 atanh x = 0.5 * log ((one+x)/(one-x))
440 /// Import mathematical functions ///
443 importJava "java.lang.Math" where
448 sinDouble :: Double -> Double
451 cosDouble :: Double -> Double
454 tanDouble :: Double -> Double
457 asinDouble :: Double -> Double
460 acosDouble :: Double -> Double
463 atanDouble :: Double -> Double
466 atan2Double :: Double -> Double -> Double
469 sinhDouble :: Double -> Double
472 coshDouble :: Double -> Double
475 tanhDouble :: Double -> Double
478 expDouble :: Double -> Double
481 logDouble :: Double -> Double
484 powDouble :: Double -> Double -> Double
487 sqrtDouble :: Double -> Double
490 ceilDouble :: Double -> Double
493 floorDouble :: Double -> Double
496 roundDouble :: Double -> Long
499 absInteger :: Integer -> Integer
502 absLong :: Long -> Long
505 absFloat :: Float -> Float
508 absDouble :: Double -> Double
511 minInteger :: Integer -> Integer -> Integer
514 minLong :: Long -> Long -> Long
517 minFloat :: Float -> Float -> Float
520 minDouble :: Double -> Double -> Double
523 maxInteger :: Integer -> Integer -> Integer
526 maxLong :: Long -> Long -> Long
529 maxFloat :: Float -> Float -> Float
532 maxDouble :: Double -> Double -> Double
537 importJava "java.lang.Byte" where
539 showByte :: Byte -> String
542 readByte :: String -> Byte
544 instance Ord Byte where
550 instance Additive Byte where
551 zero = Java.i2b Java.iconst_0
554 instance Ring Byte where
557 one = Java.i2b Java.iconst_1
559 fromInteger = Java.i2b
561 instance Show Byte where
563 precedence v = if v >= 0 then 0 else 100
565 instance Read Byte where
570 importJava "java.lang.Short" where
572 showShort :: Short -> String
575 readShort :: String -> Short
577 instance Ord Short where
583 instance Additive Short where
587 instance Ring Short where
592 fromInteger = Java.i2s
594 instance Show Short where
596 precedence v = if v >= 0 then 0 else 100
598 instance Read Short where
604 importJava "java.lang.Integer" where
606 showInteger :: Integer -> String
609 readInteger :: String -> Integer
611 instance Ord Integer where
617 instance Additive Integer where
621 instance Ring Integer where
628 instance OrderedRing Integer where
632 instance Integral Integer where
636 instance Show Integer where
638 precedence v = if v >= 0 then 0 else 100
640 instance Read Integer where
646 importJava "java.lang.Long" where
648 showLong :: Long -> String
651 readLong :: String -> Long
653 instance Ord Long where
659 instance Additive Long where
663 instance Ring Long where
668 fromInteger = Java.i2l
670 instance OrderedRing Long where
674 instance Integral Long where
678 instance Show Long where
680 precedence v = if v >= 0 then 0 else 100
682 instance Read Long where
687 importJava "java.lang.Float" where
690 compareFloat :: Float -> Float -> Integer
694 showFloat :: Float -> String
698 readFloat :: String -> Float
700 "Converts 32-bit floating point number to a 32-bit integer with the same byte level representation."
701 floatToIntBits :: Float -> Integer
703 instance Ord Float where
704 compare = compareFloat
710 instance Additive Float where
714 instance Ring Float where
719 fromInteger = Java.i2f
721 instance OrderedRing Float where
725 instance Real Float where
727 x ^ y = Java.d2f (powDouble (Java.f2d x) (Java.f2d y))
728 pi = fromDouble piDouble
729 sqrt = Java.d2f . sqrtDouble . Java.f2d
730 exp = Java.d2f . expDouble . Java.f2d
731 log = Java.d2f . logDouble . Java.f2d
732 sin = Java.d2f . sinDouble . Java.f2d
733 cos = Java.d2f . cosDouble . Java.f2d
734 tan = Java.d2f . tanDouble . Java.f2d
735 asin = Java.d2f . asinDouble . Java.f2d
736 acos = Java.d2f . acosDouble . Java.f2d
737 atan = Java.d2f . atanDouble . Java.f2d
738 sinh = Java.d2f . sinhDouble . Java.f2d
739 cosh = Java.d2f . coshDouble . Java.f2d
740 tanh = Java.d2f . tanhDouble . Java.f2d
741 floor = Java.d2f . floorDouble . Java.f2d
742 ceil = Java.d2f . ceilDouble . Java.f2d
743 atan2 y x = Java.d2f (atan2Double (Java.f2d y) (Java.f2d x))
744 round = roundDouble . Java.f2d
745 fromDouble = Java.d2f
748 instance Show Float where
750 precedence v = if v >= 0 then 0 else 100
752 instance Read Float where
757 importJava "java.lang.Double" where
760 compareDouble :: Double -> Double -> Integer
764 showDouble :: Double -> String
767 @JavaName parseDouble
768 readDouble :: String -> Double
770 "Converts 64-bit floating point number to a 64-bit integer with the same byte level representation."
771 doubleToLongBits :: Double -> Long
773 isFinite :: Double -> Boolean
774 isNaN :: Double -> Boolean
775 isInfinite :: Double -> Boolean
777 instance Ord Double where
778 compare = compareDouble
784 instance Additive Double where
788 instance Ring Double where
793 fromInteger = Java.i2d
795 instance OrderedRing Double where
799 instance Real Double where
822 instance Show Double where
824 precedence v = if v >= 0 then 0 else 100
826 instance Read Double where
831 importJava "java.lang.Character" where
833 showCharacter :: Character -> String
835 "Returns true, if the given character is a letter."
836 isLetter :: Character -> Boolean
838 "Returns true, if the given character is a digit."
839 isDigit :: Character -> Boolean
841 instance Ord Character where
847 instance Show Character where
848 sb <+ c = sb << "'" << showCharacter c << "'"
850 "Adds a given integer to the character code."
851 addChar :: Character -> Integer -> Character
854 "Subtracts a given integer from the character code."
855 subChar :: Character -> Character -> Integer
861 The `Functor` class is used for types that can be mapped over. Instances of `Functor` should satisfy the following laws:
864 fmap (f . g) == fmap f . fmap g
866 class Functor f where
867 "Lifts a pure function to the given functor."
868 fmap :: (a -> b) -> f a -> f b
870 class CoFunctor f where
871 comap :: (a -> b) -> f b -> f a
875 class (Functor f) => Applicative f where
877 (<*>) :: f (a -> b) -> f a -> f b
878 (*>) :: f a -> f b -> f b
879 (<*) :: f a -> f b -> f a
881 u *> v = pure (const id) <*> u <*> v
882 u <* v = pure const <*> u <*> v
883 fmap f x = pure f <*> x
888 The `Monad` class defines the basic operations over a monad, a concept from a branch of mathematics known as category theory.
889 From the perspective of a SCL programmer, however, it is best to think of a monad as an abstract datatype of actions.
890 SCL's `mdo expressions provide a convenient syntax for writing monadic expressions.
892 Instances of `Monad` should satisfy the following laws:
894 return a >>= k == k a
896 m >>= (\x -> k x >>= h) == (m >>= k) >>= h
897 fmap f xs == xs >>= return . f
899 class (Functor m) => Monad m where
900 "Inject a value into the monadic type."
902 "Sequentially compose two actions, passing any value produced by the first as an argument to the second."
903 (>>=) :: m a -> (a -> m b) -> m b
905 The join function is the conventional monad join operator. It removes one level of monadic
908 For lists, `join` concatenates a list of lists:
910 join [[1,2], [3,4]] = [1, 2, 3, 4]
912 join :: m (m a) -> m a
916 Sequentially compose two actions, discarding any value produced by the first, like sequencing operators
917 (such as the semicolon) in imperative languages."
920 (>>) :: Monad m => m a -> m b -> m b
921 a >> b = a >>= (\_ -> b)
923 "While loop. `while cond body` executes the `body` while the `cond` is true."
925 while :: (<e> Boolean) -> (<e> a) -> <e> ()
926 while cond body = loop ()
927 where loop _ = if cond
928 then do body ; loop ()
932 Sequences the given monadic value infinitely:
934 repeatForever m = m >> m >> m >> ...
936 repeatForever m = m >> repeatForever m
938 replicateM :: Monad m => Integer -> m a -> m [a]
939 replicateM count m = loop count emptyList
941 loop count l | count <= 0 = return l
944 loop (count-1) (addList l v)
946 replicateM_ :: Monad m => Integer -> m a -> m ()
947 replicateM_ count m | count <= 0 = return ()
948 | otherwise = m >> replicateM_ (count-1) m
953 A class of monads with zero element satisfying
957 class (Monad m) => MonadZero m where
960 "Injects a boolean test to a type beloning to `MonadZero`."
961 guard :: MonadZero m => Boolean -> m ()
962 guard True = return ()
968 A class of monads with associative binary operator `mplus` satisfying the following laws:
972 mplus (mplus a b) c = mplus a (mplus b c)
973 mplus a b >>= k = mplus (a >>= k) (b >>= k)
975 class (MonadZero m) => MonadPlus m where
976 mplus :: m a -> m a -> m a
981 A class of monads with associative binary operator `morelse` satisfying the following laws:
985 morelse (morelse a b) c = morelse a (morelse b c)
986 morelse (return a) b = return a
988 class (MonadZero m) => MonadOr m where
989 morelse :: m a -> m a -> m a
994 A class of types that can be mapped over with effectful mapping functions.
996 class (Functor f) => FunctorE f where
998 Applies the function to all elements of the container and
999 returns the similarly shaped container with the results:
1003 map f [e1, e2, ..., eN] = [f e1, f e2, ..., f eN]
1007 map (*2) [1..5] = [2, 4, 6, 8, 10]
1009 map :: (a -> <e> b) -> f a -> <e> (f b)
1010 "Calls the given function with all elements of the given container."
1011 iter :: (a -> <e> b) -> f a -> <e> ()
1012 "Calls the given function with all elements of the given container giving also the index of the element as a parameter."
1013 iterI :: (Integer -> a -> <e> b) -> f a -> <e> ()
1015 "Iterates the elements of the given collection. Same as `iter` but parameters flipped."
1016 for :: FunctorE f => f a -> (a -> <e> b) -> <e> ()
1020 "Iterates the elements of the given collection providing also the indices of the elements. Same as `iterI` but parameters flipped."
1021 forI :: FunctorE f => f a -> (Integer -> a -> <e> b) -> <e> ()
1023 forI l f = iterI f l
1025 "`forN n f` calls `f` for all integers `0`, ..., `n-1`"
1027 forN :: Integer -> (Integer -> <e> b) -> <e> ()
1031 then do f i ; loop (i+1)
1035 mapI :: (Integer -> a -> <e> b) -> [a] -> <e> [b]
1036 mapI f l = build (\empty cons -> let
1038 loop i accum = if i < len
1039 then loop (i+1) (cons accum (f i (l!i)))
1044 `mapMaybe` combines `map` and `filter` functions.
1045 It applies the given function to every element of the input list. If the result
1046 is `Just x`, then `x` is added to the resulting list.
1048 mapMaybe f lst = [y | x <- lst, Just y = f x]
1051 mapMaybe :: (a -> <e> Maybe b) -> [a] -> <e> [b]
1052 mapMaybe f l = build (\empty cons -> foldl (\cur x -> match f x with Just v -> cons cur v ; _ -> cur) empty l)
1055 Applies the given function to all elements of the list. Produces two lists: the first contains all elements `x`
1056 for which the function returned `Left x` and the second list contains all elements `y` for which the function
1059 mapEither :: (a -> <e> Either b c) -> [a] -> <e> ([b], [c])
1060 mapEither f list = runProc do
1063 for list (\x -> match f x with
1064 Left v -> addArrayList l v
1065 Right v -> addArrayList r v)
1066 (Java.unsafeCoerce l, Java.unsafeCoerce r)
1068 "`replicate n v` returns a list of length `n` such that each element is a copy of `v`."
1070 replicate :: Integer -> a -> [a]
1071 replicate n v = build (\empty cons ->
1073 aux i l = aux (i-1) (cons l v)
1079 class (Functor f) => FunctorM f where
1080 "`mapM f` is equivalent to `sequence . map f`."
1081 mapM :: Monad m => (a -> m b) -> f a -> m (f b)
1082 "Evaluate each action in the sequence from left to right, and collect the results."
1083 sequence :: Monad m => f (m a) -> m (f a)
1084 mapM f l = sequence (fmap f l)
1088 "Identity function."
1093 Ignores the given value. This function is used in a situation where a function returns
1094 a value in a context where the value is not expected.
1101 ignoreM :: a -> Maybe b
1105 Composes two functions
1108 (.) :: (b -> <e> c) -> (a -> <e> b) -> (a -> <e> c)
1113 "A type class for sequences. All sequences must support indexing by integers."
1114 class /*(Additive a) =>*/ Sequence a where
1115 "Length of the sequence"
1116 length :: a -> Integer
1117 "`take n s` returns the first `n` elements of the sequence `s`."
1118 take :: Integer -> a -> a
1119 "`drop n s` removes the first `n` elements of the sequence `s`."
1120 drop :: Integer -> a -> a
1122 `sub s begin end` returns a subsequence of `s` starting from
1123 index `begin` and ending just before index `end`.
1125 sub :: a -> Integer -> Integer -> a
1127 take n v = sub v 0 (min n (length v))
1128 drop n v = sub v (min n len) len
1132 instance Sequence [a] where
1136 instance Sequence String where
1137 length = lengthString
1140 class IndexedSequence f where
1141 "`seq ! i` returns the `i`th element of the sequence `seq`. Indexing starts from zero."
1142 (!) :: f a -> Integer -> a
1144 instance IndexedSequence [] where
1150 Equivalent to the boolean value `True`. The value is meant to be used in
1157 otherwise :: Boolean
1160 instance Ord Boolean where
1161 compare False False = 0
1162 compare False True = neg 1
1163 compare True False = 1
1164 compare True True = 0
1166 instance Show Boolean where
1168 show False = "False"
1171 Boolean conjunction (and). The function is a macro that evaluates the second parameter
1172 only if the first parameter is `True`.
1175 <tr><th>a</th><th>b</th><th>a && b</th></tr>
1176 <tr><td>True</td><td>True</td><td>True</td></tr>
1177 <tr><td>True</td><td>False</td><td>False</td></tr>
1178 <tr><td>False</td><td>not evaluated</td><td>False</td></tr>
1182 (&&) :: Boolean -> Boolean -> Boolean
1183 a && b = if a then b else False
1186 Boolean disjunction (or). The function is a macro that evaluates the second parameter
1187 only if the first parameter is `False`.
1190 <tr><th>a</th><th>b</th><th>a || b</th></tr>
1191 <tr><td>True</td><td>not evaluated</td><td>True</td></tr>
1192 <tr><td>False</td><td>True</td><td>True</td></tr>
1193 <tr><td>False</td><td>False</td><td>False</td></tr>
1197 (||) :: Boolean -> Boolean -> Boolean
1198 a || b = if a then True else b
1202 not a = if a then False else True
1206 //data Maybe a = Nothing | Just a
1208 "Given `Just x` this function returns `x`. If the parameter is `Nothing`, the function raises an exception."
1209 fromJust :: Maybe a -> a
1210 fromJust (Just a) = a
1212 deriving instance (Ord a) => Ord (Maybe a)
1213 deriving instance (Show a) => Show (Maybe a)
1215 instance Functor Maybe where
1216 fmap _ Nothing = Nothing
1217 fmap f (Just x) = Just (f x)
1219 instance FunctorE Maybe where
1220 map _ Nothing = Nothing
1221 map f (Just x) = Just (f x)
1224 iter f (Just x) = ignore (f x)
1226 iterI _ Nothing = ()
1227 iterI f (Just x) = ignore (f 0 x)
1229 instance Monad Maybe where
1233 Nothing >>= _ = Nothing
1237 join Nothing = Nothing
1240 instance MonadZero Maybe where
1243 instance MonadOr Maybe where
1244 morelse a@(Just _) _ = a
1247 "`execJust v f` executes the function `f` with parameter value `x`, if `v=Just x`. If `v=Nothing`, the function does nothing."
1249 execJust :: Maybe a -> (a -> <e> b) -> <e> ()
1250 execJust maybeValue procedure = match maybeValue with
1251 Just v -> ignore $ procedure v
1254 "`fromMaybe def v` returns `def` if `v=Nothing` and `x` if `v=Just x`."
1256 fromMaybe :: a -> Maybe a -> a
1257 fromMaybe default maybeValue = match maybeValue with
1263 Provides a default value if the first parameter is Nothing.
1264 The default value is evaluated only if needed. The function
1265 can be used as an operator and is right associative so that
1266 the following is possible:
1268 tryWithTheFirstMethod
1269 `orElse` tryWithTheSecondMethod
1270 `orElse` fail "Didn't succeed."
1273 orElse :: Maybe a -> (<e> a) -> <e> a
1274 orElse (Just x) _ = x
1275 orElse Nothing def = def
1280 The Either type represents values with two possibilities: a value of type `Either a b` is either `Left a` or `Right b`.
1282 The `Either` type is sometimes used to represent a value which is either correct or an error; by convention, the `Left` constructor
1283 is used to hold an error value and the `Right` constructor is used to hold a correct value (mnemonic: "right" also means "correct").
1285 @JavaType "org.simantics.scl.runtime.either.Either"
1287 @JavaType "org.simantics.scl.runtime.either.Left"
1290 | @JavaType "org.simantics.scl.runtime.either.Right"
1294 deriving instance (Ord a, Ord b) => Ord (Either a b)
1295 deriving instance (Show a, Show b) => Show (Either a b)
1297 instance Functor (Either a) where
1298 fmap _ (Left x) = Left x
1299 fmap f (Right y) = Right (f y)
1301 instance FunctorE (Either a) where
1302 map _ (Left x) = Left x
1303 map f (Right y) = Right (f y)
1305 iter _ (Left x) = ()
1306 iter f (Right y) = ignore (f y)
1308 iterI _ (Left x) = ()
1309 iterI f (Right y) = ignore (f 0 y)
1311 instance Monad (Either b) where
1314 Left x >>= _ = Left x
1317 join (Left x) = Left x
1322 importJava "java.lang.String" where
1325 concatString :: String -> String -> String
1327 @JavaName "compareTo"
1328 compareString :: String -> String -> Integer
1331 lengthString :: String -> Integer
1334 `replaceString original pattern replacement` replaces all occurrences of `pattern` in the string by `replacement`.
1337 replaceString :: String -> String -> String -> String
1341 splitString_ :: String -> String -> Array String
1344 `indexOf string s` finds the first occurrence of `s` from `string` and returns its index.
1345 If the `s` does not occur in the string, return `-1`."
1348 indexOf :: String -> String -> Integer
1350 "Works like `indexOf` but starts searching from the given index instead of the beginning of the string."
1352 indexOfStartingFrom :: String -> String -> Integer -> Integer
1354 "Works like `indexOf` but returns the index of the last occurrence."
1355 @JavaName lastIndexOf
1356 lastIndexOf :: String -> String -> Integer
1358 "Works like `lastIndexOf` but starts searching from the given index instead of the end of the string."
1359 @JavaName lastIndexOf
1360 lastIndexOfStartingFrom :: String -> String -> Integer -> Integer
1364 subString :: String -> Integer -> Integer -> String
1367 `regionMatches str1 offset1 str2 offset2 len` tests whether
1368 `sub str1 offset1 (offset1+len) == sub str2 offset2 (offset2+len)`.
1370 regionMatches :: String -> Integer -> String -> Integer -> Integer -> Boolean
1372 "`startsWith string prefix` returns true if the string begins with the given prefix."
1373 startsWith :: String -> String -> Boolean
1375 "`endsWith string suffix` returns true if the string ends with the given prefix."
1376 endsWith :: String -> String -> Boolean
1378 "Removes leading and trailing whitespace from the string."
1379 trim :: String -> String
1381 "`contains string s` returns true if `string` contains `s` as a substring."
1382 contains :: String -> String -> Boolean
1384 "`charAt string i` returns the `i`th character of the string."
1385 charAt :: String -> Integer -> Character
1387 "Converts all letters of the string to lower case."
1388 toLowerCase :: String -> String
1389 "Converts all letters of the string to upper case."
1390 toUpperCase :: String -> String
1392 "Creates a string from a vector of characters."
1394 string :: Vector Character -> String
1396 instance Ord String where
1397 compare = compareString
1399 instance Additive String where
1402 sum ss = runProc (StringBuilder.toString $ foldl StringBuilder.appendString StringBuilder.new ss)
1405 importJava "org.simantics.scl.runtime.string.StringEscape" where
1406 appendEscapedString :: StringBuilder.T -> String -> <Proc> StringBuilder.T
1408 instance Show String where
1409 showForPrinting = id
1410 sb <+ v = (appendEscapedString (sb << "\"") v) << "\""
1412 instance Read String where
1415 @deprecated "Instead of 'splitString text pattern', write 'split pattern text' (note change in the parameter order)."
1416 "`splitString text pattern` splits the string into a list of string where the parts are sepratated in the original list by the given pattern."
1417 splitString :: String -> String -> [String]
1418 splitString source pattern = arrayToList $ splitString_ source pattern
1420 split :: String -> String -> [String]
1421 split pattern text = arrayToList $ splitString_ text pattern
1425 instance Ord () where
1428 instance Additive () where
1432 instance Show () where
1437 "Gives the first element of a pair."
1442 "Gives the second element of a pair."
1447 instance (Ord a, Ord b) => Ord (a, b) where
1448 compare (a0, b0) (a1, b1) = compare a0 a1 &<& compare b0 b1
1450 instance (Additive a, Additive b) => Additive (a, b) where
1452 (a0, b0) + (a1, b1) = (a0+a1, b0+b1)
1454 instance Functor ((,) a) where
1455 fmap f (a,b) = (a, f b)
1457 instance (Show a, Show b) => Show (a, b) where
1458 sb <+ (x, y) = sb << "(" <+ x << ", " <+ y << ")"
1462 instance (Ord a, Ord b, Ord c) => Ord (a, b, c) where
1463 compare (a0, b0, c0) (a1, b1, c1) = compare a0 a1 &<& compare b0 b1 &<& compare c0 c1
1465 instance (Additive a, Additive b, Additive c) => Additive (a, b, c) where
1466 zero = (zero, zero, zero)
1467 (a0, b0, c0) + (a1, b1, c1) = (a0+a1, b0+b1, c0+c1)
1469 instance Functor ((,,) a b) where
1470 fmap f (a,b,c) = (a, b, f c)
1472 instance (Show a, Show b, Show c) => Show (a, b, c) where
1473 sb <+ (x, y, z) = sb << "(" <+ x << ", " <+ y << ", " <+ z << ")"
1477 instance (Ord a, Ord b, Ord c, Ord d) => Ord (a, b, c, d) where
1478 compare (a0, b0, c0, d0) (a1, b1, c1, d1) =
1479 compare a0 a1 &<& compare b0 b1 &<& compare c0 c1 &<& compare d0 d1
1481 instance (Additive a, Additive b, Additive c, Additive d) => Additive (a, b, c, d) where
1482 zero = (zero, zero, zero, zero)
1483 (a0, b0, c0, d0) + (a1, b1, c1, d1) = (a0+a1, b0+b1, c0+c1, d0+d1)
1485 instance Functor ((,,,) a b c) where
1486 fmap f (a,b,c,d) = (a, b, c, f d)
1488 instance (Show a, Show b, Show c, Show d) => Show (a, b, c, d) where
1489 sb <+ (x, y, z, w) = sb << "(" <+ x << ", " <+ y << ", " <+ z << ", " <+ w << ")"
1493 instance (Ord a, Ord b, Ord c, Ord d, Ord e) => Ord (a, b, c, d, e) where
1494 compare (a0, b0, c0, d0, e0) (a1, b1, c1, d1, e1) =
1495 compare a0 a1 &<& compare b0 b1 &<& compare c0 c1 &<& compare d0 d1 &<& compare e0 e1
1497 instance (Additive a, Additive b, Additive c, Additive d, Additive e) => Additive (a, b, c, d, e) where
1498 zero = (zero, zero, zero, zero, zero)
1499 (a0, b0, c0, d0, e0) + (a1, b1, c1, d1, e1) = (a0+a1, b0+b1, c0+c1, d0+d1, e0+e1)
1501 instance Functor ((,,,,) a b c d) where
1502 fmap f (a,b,c,d,e) = (a, b, c, d, f e)
1506 instance (Ord a) => Ord [a] where
1507 compare a b = loop 0
1512 then (if i >= lB then 0 else -1)
1515 else compare (a!i) (b!i) &<& loop (i+1)
1517 instance Functor [] where
1520 instance FunctorE [] where
1525 instance Monad [] where
1526 return x = singletonList x
1527 l >>= f = concatMap f l
1530 instance MonadZero [] where
1533 instance MonadPlus [] where
1536 instance Additive [a] where
1540 instance FunctorM [] where
1541 sequence = foldl (\m mel -> m >>= \l -> mel >>= \el -> return (addList l el)) (return emptyList)
1542 mapM f l = sequence (map f l)
1544 "Appends the string representations of all elements of the list to the string builder and separates the values with the given separator."
1545 printWithSeparator :: Show a => StringBuilder.T -> String -> [a] -> <Proc> StringBuilder.T
1546 printWithSeparator sb sep l = loop 0
1549 loop i = if i >= len then sb
1551 (if i==0 then sb else sb << sep) <+ l!i
1554 "Joins the string representations of the list of values with the given separator."
1555 joinWithSeparator :: Show a => String -> [a] -> String
1556 joinWithSeparator separator values = runProc (
1557 StringBuilder.toString $ printWithSeparator StringBuilder.new separator values)
1560 intercalate :: String -> [String] -> String
1561 intercalate separator strings = do
1568 sb = StringBuilder.new
1570 loop i | i == l = ()
1572 sb << separator << strings!i
1575 StringBuilder.toString sb
1577 instance (Show a) => Show [a] where
1582 if (i>0) then sb << ", " else sb
1589 importJava "java.util.List" where
1590 "`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."
1592 getList :: [a] -> Integer -> a
1596 lengthList :: [a] -> Integer
1599 subList :: [a] -> Integer -> Integer -> [a]
1602 isEmpty :: [a] -> Boolean
1605 importJava "java.util.Collections" where
1607 //singletonList :: a -> [a]
1612 emptyList = build (\empty cons -> empty)
1615 "Creates a list with exectly one element."
1617 singletonList :: a -> [a]
1618 singletonList v = build (\empty cons -> cons empty v)
1621 // foldl f i (a + b) = foldl f (foldl f i a) b
1623 appendList :: [a] -> [a] -> [a]
1624 appendList a b = build (\empty cons -> foldl cons (foldl cons empty a) b)
1627 importJava "org.simantics.scl.runtime.list.ShareableList" where
1628 "Concatenates two lists."
1631 appendList :: [a] -> [a] -> [a]
1633 "Adds the given value to the end of the list."
1635 addList :: [a] -> a -> [a]
1638 importJava "java.util.ArrayList" where
1642 newArrayList :: <Proc> ArrayList a
1645 addArrayList :: ArrayList a -> a -> <Proc> ()
1648 A primitive for constructing a list by `empty` and `cons` operations given to the function given as a parameter to this function.
1651 build (\empty cons -> cons (cons (cons empty 1) 2) 3)
1657 The SCL compiler makes the following optimization when encountering `build` and `foldl` functions after inlining:
1659 foldl f i (build g) = g i f
1662 build :: forall b e2. (forall a e1. a -> (a -> b -> <e1> a) -> <e1,e2> a) -> <e2> [b]
1663 build f = runProc do
1665 f () (\_ v -> addArrayList l v)
1668 "A specific implementation of `map` for lists."
1671 mapEList :: (a -> <e> b) -> [a] -> <e> [b]
1672 mapEList f l = build (\empty cons -> foldl (\cur x -> cons cur (f x)) empty l)
1674 "A specific implementation of `fmap` for lists."
1676 mapList :: (a -> b) -> [a] -> [b]
1677 mapList f l = build (\empty cons -> foldl (\cur x -> cons cur (f x)) empty l)
1679 "`guardList v` returns a singleton `[()]` if `v=True` and the empty list if `v=False`."
1681 guardList :: Boolean -> [()]
1682 guardList cond = build (\empty cons -> if cond then cons empty () else empty)
1685 `concatMap` combines `map` and `join` functions.
1686 It maps the elements of a given list to lists with the given function and concatenates the results.
1688 concatMap f lst = join (map f lst) = [y | x <- lst, y <- f x]
1691 concatMap :: (a -> <e> [b]) -> [a] -> <e> [b]
1692 concatMap f l = build (\empty cons -> foldl (\cur le -> foldl cons cur (f le)) empty l)
1695 Applies the given function to the elements of the lists until the function returns something
1696 else than `Nothing`. This return value is also returned as a result of this function.
1699 mapFirst :: (a -> <e> Maybe b) -> [a] -> <e> Maybe b
1700 mapFirst f l = loop 0
1703 loop i = if i == len
1705 else match f (l!i) with
1707 Nothing -> loop (i+1)
1710 foldl op initialValue list
1712 applies a binary operator `op` to all elements of `list` from left to right
1713 starting with `initialValue`. For example,
1715 foldl op init [x1, x2, x3, x4] = (((init `op` x1) `op` x2) `op` x3) `op` x4
1718 foldl :: forall a b e. (a -> b -> <e> a) -> a -> [b] -> <e> a
1719 foldl f initial l = loop initial 0
1722 loop cur i = if i==len
1724 else loop (f cur (l!i)) (i+1)
1726 foldlI :: forall a b e. (Integer -> a -> b -> <e> a) -> a -> [b] -> <e> a
1727 foldlI f initial l = loop initial 0
1730 loop cur i = if i==len
1732 else loop (f i cur (l!i)) (i+1)
1734 scanl :: (b -> a -> <e> b) -> b -> [a] -> <e> [b]
1735 scanl f initial l = build (\empty cons -> let
1737 loop cur i accum = let nl = cons accum cur
1740 else loop (f cur (l!i)) (i+1) nl
1741 in loop initial 0 empty)
1743 "`foldr` is defined like `foldl` but it process the list from right to left."
1745 foldr :: (b -> a -> <e> a) -> a -> [b] -> <e> a
1746 foldr f initial l = loop initial (length l - 1)
1748 loop cur i = if i < 0
1750 else loop (f (l!i) cur) (i-1)
1752 foldr1 :: (a -> a -> <e> a) -> [a] -> <e> a
1753 foldr1 f l = loop (l!(len-1)) (len-2)
1756 loop cur i = if i < 0
1758 else loop (f (l!i) cur) (i-1)
1761 `filter pred lst` returns those elements of `lst` that the predicate `pred` accepts. For example
1763 filter (> 3) [1, 2, 3, 4, 5, 6] = [4, 5, 6]
1766 filter :: (a -> <e> Boolean) -> [a] -> <e> [a]
1767 filter p l = build (\empty cons -> foldl (\cur x -> if p x then cons cur x else cur) empty l)
1770 Takes those elements of the input list that match `(Just x)` and adds the contents to the resulting list. For example,
1772 filterJust [Just 1, Nothing, Just 5] = [1, 5]
1775 filterJust :: [Maybe a] -> [a]
1776 filterJust l = build (\empty cons -> foldl (\cur x -> match x with Just v -> cons cur v ; _ -> cur) empty l)
1778 listToMaybe :: [a] -> Maybe a
1779 listToMaybe l = if isEmpty l then Nothing else Just (l!0)
1781 maybeToList :: Maybe a -> [a]
1782 maybeToList (Just a) = [a]
1786 `takeWhile p l`, returns the longest prefix (possibly empty) of list `l` of elements that satisfy `p`
1788 takeWhile :: (a -> <e> Boolean) -> [a] -> <e> [a]
1789 takeWhile f l = loop 0
1792 loop i | i == len = l
1793 | f (l!i) = loop (i+1)
1794 | otherwise = take i l
1796 partition :: (a -> <e> Boolean) -> [a] -> <e> ([a], [a])
1797 partition p l = runProc do
1802 then addArrayList res1 el
1803 else addArrayList res2 el
1805 (Java.unsafeCoerce res1, Java.unsafeCoerce res2)
1808 `range begin end` produces a list of consecutive integers starting from `begin` and ending to `end` (including `end`).
1809 The compiler supports syntactic sugar `[begin..end]` for this function.
1812 range :: Integer -> Integer -> [Integer]
1813 range first last = build (\empty cons -> do
1814 loop i cur = if i > last then cur else loop (i+1) (cons cur i)
1817 "A specific implementation of `iter` for lists."
1819 iterList :: (a -> <e> b) -> [a] -> <e> ()
1820 iterList f l = foldl (\_ x -> ignore (f x)) () l
1822 "A specific implementation of `iterI` for lists."
1824 iterIList :: (Integer -> a -> <e> b) -> [a] -> <e> ()
1825 iterIList f l = do foldl (\i x -> do f i x ; i+1) 0 l ; ()
1828 Generates a list from a given starting state and iteration function.
1831 let nextState 0 = Nothing
1832 nextState i = Just (i, i `div` 2)
1833 in unfoldr nextState 30
1840 unfoldr :: (b -> <e> Maybe (a, b)) -> b -> <e> [a]
1841 unfoldr f s = build (\empty cons -> do
1844 Just (el,newS) -> loop newS (cons cur el)
1848 importJava "org.simantics.scl.runtime.Lists" where
1852 mapList :: (a -> b) -> [a] -> [b]
1855 mapEList :: (a -> <e> b) -> [a] -> <e> [b]
1858 iterList :: (a -> <e> ()) -> [a] -> <e> ()
1859 concatMap :: (a -> <e> [b]) -> [a] -> <e> [b]
1862 Combines two lists into one list of pairs. The length of the resulting list is the length of the smallest input list.
1864 zip [1, 2, 3, 4, 5] ['a', 'b', 'c'] = [(1, 'a'), (2, 'b'), (3, 'c')]
1866 zip :: [a] -> [b] -> [(a,b)]
1867 "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."
1868 zipWith :: (a -> b -> <e> c) -> [a] -> [b] -> <e> [c]
1870 Produces two lists from one list of pairs.
1872 unzip [(1, 'a'), (2, 'b'), (3, 'c')] = ([1, 2, 3], ['a', 'b', 'c'])
1874 unzip :: [(a,b)] -> ([a],[b])
1876 //"@filter p l@ returns those elements of @l@ that the predicate @p@ accepts."
1877 //filter :: (a -> <e> Boolean) -> [a] -> <e> [a]
1878 //filterJust :: [Maybe a] -> [a]
1880 foldl :: (a -> b -> <e> a) -> a -> [b] -> <e> a
1882 "Like `foldl` but assumes that the list is non-empty so the initial is not needed."
1883 foldl1 :: (a -> a -> <e> a) -> [a] -> <e> a
1884 //unfoldr :: (b -> <e> Maybe (a, b)) -> b -> <e> [a]
1886 "Sorts the list using the given comparator."
1887 sortWith :: (a -> a -> <e> Integer) -> [a] -> <e> [a]
1888 "Works like `index` but uses the given functions as hash codes and equality."
1889 indexWith :: (a -> Integer) -> (a -> a -> Boolean) -> [(a,b)] -> a -> Maybe b
1890 groupWith :: (b -> Integer) -> (b -> b -> Boolean) -> (a -> <e> b) -> (a -> <e> c) -> [a] -> <e> [(b, [c])]
1891 "Works like `unique` but uses the given function for equality tests."
1892 uniqueWith :: (a -> a -> Boolean) -> [a] -> [a]
1893 "Works like `\\\\` but uses the given function for equality tests."
1894 deleteAllBy :: (a -> a -> Boolean) -> [a] -> [a] -> [a]
1896 //range :: Integer -> Integer -> [Integer]
1898 //build :: (forall a. a -> (a -> b -> <e> a) -> <e> a) -> <e> [b]
1900 "`elem el lst` return true, if `el` occurs in the list `lst`."
1901 elem :: a -> [a] -> Boolean
1905 loop i | i < len = if el == l!i
1910 "`elemMaybe v1 (Just v2)` returns true if `v1 == v2`. `elemMaybe v1 Nothing` is always false."
1911 elemMaybe :: a -> Maybe a -> Boolean
1912 elemMaybe el m = match m with
1913 Just el2 -> el == el2
1917 Computes a list that contains only elements that belongs to both input lists.
1919 intersect :: [a] -> [a] -> [a]
1920 intersect a b = filter f a
1924 "Reverses a given list. For example, `reverse [1,2,3] = [3,2,1]`"
1925 reverse :: [a] -> [a]
1926 reverse l = [l!(len-i) | i <- [1..len]]
1931 Transposes the rows and columns of its argument. For example,
1933 transpose [[1,2,3],[4,5,6]] == [[1,4],[2,5],[3,6]]
1934 transpose [[1,2],[3,4,5]] == [[1,3],[2,4],[5]]
1936 transpose xss = [[xs!i | xs <- xss, i < length xs]
1937 | i <- [0..maximum [length xs | xs <- xss]-1]]
1939 "Works like `unfoldr` but generates the list from right to left."
1940 unfoldl :: (b -> <e> Maybe (a, b)) -> b -> <e> [a]
1941 unfoldl f seed = reverse $ unfoldr f seed
1943 "Removes the first element of the list, if the list is non-empty."
1945 tail l = if len < 2 then emptyList else subList l 1 len
1949 "Tries to find the given key from the list of key-value pairs and returns the corresponding value."
1950 lookup :: a -> [(a, b)] -> Maybe b
1955 (a,b) | a == el -> Just b
1956 | otherwise -> loop (i+1)
1960 "Conjunction over a list."
1962 and :: [Boolean] -> Boolean
1963 and = foldl (&&) True
1965 "Disjunction over a list."
1967 or :: [Boolean] -> Boolean
1968 or = foldl (||) False
1971 `any pred lst` tests whether the predicate `pred` holds some element of `lst`.
1972 It returns immediately when it encounters the first value satisfying the predicate.
1974 any :: (a -> <e> Boolean) -> [a] -> <e> Boolean
1978 `all pred lst` tests whether the predicate `pred` holds for all elements of `lst`.
1979 It returns immediately when it encounters the first value not satisfying the predicate.
1981 all :: (a -> <e> Boolean) -> [a] -> <e> Boolean
1985 Returns the first element of the list satisfying the given condition,
1986 or `Nothing` if there is no such element.
1988 findFirst :: (a -> <e> Boolean) -> [a] -> <e> Maybe a
1989 findFirst p l = loop 0
1993 then let el = l!i in
2002 Sorts the given list using its default order.
2005 sort :: Ord a => [a] -> [a]
2006 sort = sortWith compare
2009 Sorts the lists by the values computed by the first function.
2012 sortBy snd [(1,5), (2,3), (3,4)] = [(2,3), (3,4), (1,5)]
2015 sortBy :: Ord b => (a -> <e> b) -> [a] -> <e> [a]
2016 sortBy f l = sortWith (\x y -> compare (f x) (f y)) l
2017 // This is faster if f is slow, but will generate more auxiliary structures
2018 //sortBy f l = map snd (sortWith (\(x,_) (y,_) -> compare x y) [(f x, x) | x <- l])
2021 Given a list of key-value pairs, the function produces a function that finds a value
2022 efficiently for the given key.
2024 index :: [(a,b)] -> a -> Maybe b
2025 index = indexWith hashCode (==)
2028 Given a list of values and a function computing a key for each value, the function produces a function that finds a value
2029 effeciently for the given key.
2031 indexBy :: (a -> b) -> [a] -> b -> Maybe a
2032 indexBy f l = index [(f x, x) | x <- l]
2034 "Groups a list values by a key computed by the given function."
2035 groupBy :: (a -> <e> b) -> [a] -> <e> [(b, [a])]
2036 groupBy f l = groupWith hashCode (==) f id l
2038 "Groups a list of key-value pairs by the keys."
2039 group :: [(a,b)] -> [(a, [b])]
2040 group = groupWith hashCode (==) fst snd
2042 "Removes duplicates (all but the first occurrence) from the list but otherwise preserves the order of the elements."
2043 unique :: [a] -> [a]
2044 unique = uniqueWith (==)
2046 "Like `unique`, but uses the given function for finding the key values used for uniqueness testing."
2047 uniqueBy :: (a -> b) -> [a] -> [a]
2048 uniqueBy f = uniqueWith (\a b -> f a == f b)
2050 //sortAndUniqueBy :: Ord b => (a -> b) -> [a] -> [a]
2051 //sortAndUniqueBy f = map snd . uniqueWith (\a b -> fst a == fst b) . sortBy fst . map (\x -> (f x, x))
2053 "`a \\\\ b` removes all elements of `b` from the list `a`."
2054 (\\) :: [a] -> [a] -> [a]
2055 (\\) = deleteAllBy (==)
2059 importJava "java.lang.Object" where
2060 "A data type that can represent any value."
2065 showDynamic :: Dynamic -> String
2067 instance Show Dynamic where
2070 "Converts a value to `Dynamic` type."
2071 toDynamic :: a -> Dynamic
2072 toDynamic = Java.unsafeCoerce
2074 "Converts a `Dynamic` value to a required value, or fails if the conversion is not possible."
2075 importJava "org.simantics.scl.compiler.runtime.ValueConversion" where
2076 fromDynamic :: Typeable a => Dynamic -> a
2080 importJava "org.simantics.scl.runtime.procedure.Ref" where
2081 "A mutable reference to a value of type `a`."
2084 "Creates a new reference with the given initial value."
2086 ref :: a -> <Proc> (Ref a)
2088 "Returns the current value of the reference."
2090 getRef :: Ref a -> <Proc> a
2092 "Sets a new value for the reference."
2093 @JavaName "<set>value"
2094 (:=) :: Ref a -> a -> <Proc> ()
2096 instance Show (Ref a) where
2097 show _ = "<reference>"
2099 importJava "org.simantics.scl.runtime.reporting.SCLReporting" where
2100 "Prints the given string to the console."
2102 printString :: String -> <Proc> ()
2103 "Prints an error message to the console."
2104 printError :: String -> <Proc> ()
2105 "Reports that certain amount of work has been done for the current task."
2106 didWork :: Double -> <Proc> ()
2108 `printingToFile "fileName" expression` executes the `expression` so that all its console prints
2109 are written to the file given as a first parameter.
2111 printingToFile :: String -> (<e> a) -> <e> a
2113 `printErrorsAsNormalPrints expression` executes the `expression` so that all its error prints
2114 are printed as normal prints. This is useful mainly in testing scripts for checking that the implementations
2115 give proper error messages with invalid inputs.
2117 printErrorsAsNormalPrints :: (<e> a) -> <e> a
2119 `disablePrintingForCommand expression` executes the `expression` so that it does not print return values.
2120 Errors are printed normally.
2122 disablePrintingForCommand :: (<e> a) -> <e> a
2125 importJava "org.simantics.scl.runtime.procedure.Procedures" where
2126 "Returns `True` if the current thread has been interrupted."
2127 isInterrupted :: <Proc> Boolean
2128 "Checks whether the current thread has been interrupted and throws an exception if it is."
2129 checkInterrupted :: <Proc> ()
2130 "Generates a random identifier."
2131 generateUID :: <Proc> String
2133 "Executes the given expression and catches certain class of exceptions (specified by the catch handler that is given as a second parameter.)"
2135 catch :: VecComp ex => (<e,Exception> a) -> (ex -> <e> a) -> <e> a
2137 importJava "java.lang.Throwable" where
2141 showThrowable :: Throwable -> String
2142 importJava "java.lang.Exception" where
2146 showException :: Exception -> String
2148 instance Show Throwable where
2149 show = showThrowable
2150 instance Show Exception where
2151 show = showException
2153 "Prints the given value in the console."
2155 print :: Show a => a -> <Proc> ()
2156 print v = printString (showForPrinting v)
2158 instance Show TypeRep where
2159 sb <+ (TApply (TCon "Builtin" "[]") b) =
2160 sb << "[" <+ b << "]"
2161 sb <+ (TApply (TApply (TCon "Builtin" "(,)") c1) c2) =
2162 sb << "(" <+ c1 << "," <+ c2 << ")"
2163 sb <+ (TApply (TApply (TApply (TCon "Builtin" "(,,)") c1) c2) c3) =
2164 sb << "(" <+ c1 << "," <+ c2 << "," <+ c3 << ")"
2165 sb <+ (TApply (TApply (TApply (TApply (TCon "Builtin" "(,,,)") c1) c2) c3) c4) =
2166 sb << "(" <+ c1 << "," <+ c2 << "," <+ c3 << "," <+ c4 << ")"
2168 sb <+ (TCon _ name) = sb << name
2169 sb <+ (TApply a b) = sb <+ Par 1 a << " " <+ Par 2 b
2170 sb <+ (TFun a b) = sb <+ Par 1 a << " -> " <+ b
2172 precedence (TCon _ _) = 0
2173 precedence (TFun _ _) = 2
2174 precedence (TApply a _) = if isSpecialType a then 0 else 1
2176 isSpecialType (TCon "Builtin" "[]") = True
2177 isSpecialType (TCon "Builtin" "()") = True
2178 isSpecialType (TCon "Builtin" "(,)") = True
2179 isSpecialType (TCon "Builtin" "(,,)") = True
2180 isSpecialType (TCon "Builtin" "(,,,)") = True
2181 isSpecialType (TApply a _) = isSpecialType a
2186 importJava "java.util.Arrays" where
2189 byteArrayToString :: ByteArray -> String
2191 instance Show ByteArray where
2192 show = byteArrayToString
2197 importJava "org.simantics.scl.compiler.types.Type" where
2199 showType :: Type -> String
2201 importJava "org.simantics.scl.compiler.types.Types" where
2202 removeForAll :: Type -> Type
2204 instance Show Type where