Implemented many type class instances for Set.T 41/2741/2
authorHannu Niemistö <hannu.niemisto@semantum.fi>
Fri, 1 Mar 2019 11:04:14 +0000 (13:04 +0200)
committerHannu Niemistö <hannu.niemisto@semantum.fi>
Fri, 1 Mar 2019 11:07:00 +0000 (13:07 +0200)
Change-Id: I6190579fb7715ebfc5b165941cb33c6d27e84148

bundles/org.simantics.scl.runtime/scl/Iterator.scl
bundles/org.simantics.scl.runtime/scl/Prelude.scl
bundles/org.simantics.scl.runtime/scl/Set.scl
bundles/org.simantics.scl.runtime/scl/SetClasses.scl [new file with mode: 0644]
bundles/org.simantics.scl.runtime/scl/SetUtils.scl [deleted file]
bundles/org.simantics.scl.runtime/scl/StandardLibrary.scl

index 19e51a0d5836d23cb2447daabdb1d2093e6d093a..b98e14f423aaccb9252883be3d95c569833ce8bf 100644 (file)
@@ -1,3 +1,5 @@
+import "JavaBuiltin" as Java
+
 importJava "java.util.Iterator" where
     data T a
     
@@ -16,6 +18,17 @@ iter f it = loop ()
             loop ()
         else ()
 
+@inline
+iterI :: (Integer -> a -> <e> b) -> T a -> <Proc,e> ()
+iterI f it = loop 0
+  where
+    loop i = 
+        if hasNext it
+        then do
+            f i (next it)
+            loop (Java.iadd i 1)
+        else ()
+        
 @inline
 iterB :: (a -> <e> Boolean) -> T a -> <Proc,e> Boolean
 iterB f it = loop ()
index 80b4d0ad794d8eca76d5210c5783fca6cba9a933..c175f95a30d01bd7a15c0c6e9d8d4fd1dc36ef1d 100644 (file)
@@ -963,6 +963,9 @@ A class of monads with zero element satisfying
 """ 
 class (Monad m) => MonadZero m where
     mzero :: m a
+    mfilter :: (a -> Boolean) -> m a -> m a
+    
+    mfilter p m = m >>= (\x -> if p x then return x else mzero)
 
 "Injects a boolean test to a type beloning to `MonadZero`."
 guard :: MonadZero m => Boolean -> m ()
@@ -1105,7 +1108,21 @@ instance MonadE (Either a) where
 
 instance MonadE [] where
     bindE l f = concatMap f l
+
+/// MZeroE ///
+
+class (MonadE m, MonadZero m) => MonadZeroE m where
+    filter :: (a -> <e> Boolean) -> m a -> <e> m a
+    
+    filter p m = m `bindE` (\x -> if p x then return x else mzero)   
     
+instance MonadZeroE [] where
+    filter = filterList
+    
+instance MonadZeroE Maybe where
+    filter p (Just x) | not (p x) = Nothing
+    filter _ m = m 
+
 /// Category ///
 
 "Identity function."
@@ -1841,10 +1858,10 @@ foldr1 f l = loop (l!(len-1)) (len-2)
 `filter pred lst` returns those elements of `lst` that the predicate `pred` accepts. For example
 
     filter (> 3) [1, 2, 3, 4, 5, 6] = [4, 5, 6]
-""" 
+"""
 @inline
-filter :: (a -> <e> Boolean) -> [a] -> <e> [a]
-filter p l = build (\empty cons -> foldl (\cur x -> if p x then cons cur x else cur) empty l)
+filterList :: (a -> <e> Boolean) -> [a] -> <e> [a]
+filterList p l = build (\empty cons -> foldl (\cur x -> if p x then cons cur x else cur) empty l)
 
 """
 Takes those elements of the input list that match `(Just x)` and adds the contents to the resulting list. For example,
index 2bf2911c5631cc4e33938711b3a1f6ea86c16007..34033d91ef928ff9e52f2094f1db6c225f22ddd9 100644 (file)
@@ -11,13 +11,31 @@ importJava "java.util.Set" where
     iterator :: T a -> Iterator.T a
 
 @inline
-iter :: (a -> <e> ()) -> T a -> <e> ()
+iter :: (a -> <e> b) -> T a -> <e> ()
 iter f s = runProc (Iterator.iter f (iterator s))
 
 @inline
 iterB :: (a -> <e> Boolean) -> T a -> <e> Boolean
 iterB f s = runProc (Iterator.iterB f (iterator s))
 
+@inline
+iterI :: (Integer -> a -> <e> b) -> T a -> <e> ()
+iterI f s = runProc (Iterator.iterI f (iterator s))
+
 @inline
 fold :: (a -> b  -> <e> a) -> a -> T b -> <e> a
 fold f init s = runProc (Iterator.fold f init (iterator s))
+
+importJava "java.util.Collections" where
+    singleton :: a -> T a
+
+    @JavaName emptySet
+    empty :: T a
+
+importJava "gnu.trove.set.hash.THashSet" where
+    @JavaName "<init>"
+    fromList :: [a] -> T a
+
+importJava "java.util.ArrayList" where
+    @JavaName "<init>"
+    toList :: T a -> [a]
diff --git a/bundles/org.simantics.scl.runtime/scl/SetClasses.scl b/bundles/org.simantics.scl.runtime/scl/SetClasses.scl
new file mode 100644 (file)
index 0000000..8c3d1e6
--- /dev/null
@@ -0,0 +1,61 @@
+import "Prelude"
+import "MSet" as MSet
+import "Set" as Set
+
+instance Functor Set.T where
+    fmap = map
+        
+instance FunctorE Set.T where
+    map f set = runProc do
+        result = MSet.create ()
+        Set.iter (\x -> MSet.add result $ f x) set
+        MSet.freeze result
+        
+    iter = Set.iter
+    iterI = Set.iterI
+    
+instance Monad Set.T where
+    return = Set.singleton
+    (>>=) = bindE
+
+@private
+importJava "java.util.Set" where
+    @JavaName addAll
+    addAll' :: MSet.T a -> Set.T a -> <Proc> Boolean
+        
+instance MonadE Set.T where
+    set `bindE` f = runProc do
+        result = MSet.create ()
+        Set.iter (\x -> addAll' result $ f x) set
+        MSet.freeze result
+        
+instance MonadZero Set.T where
+    mzero = Set.empty
+    
+instance MonadZeroE Set.T where
+    filter p set = runProc do
+        result = MSet.create ()
+        Set.iter (\x ->
+            if p x
+            then ignore $ MSet.add result x
+            else ()
+        ) set
+        MSet.freeze result
+
+instance (Show a) => Show (Set.T a) where
+    sb <+ set = do
+        sb << "{"
+        Set.iterI (\i x -> (if i > 0 then sb << ", " else sb) <+ x) set
+        sb << "}"
+
+instance Additive (Set.T a) where
+    zero = Set.empty
+    a + b = runProc do
+        result = MSet.create ()
+        Set.iter (MSet.add result) a
+        Set.iter (MSet.add result) b
+        MSet.freeze result
+    sum sets = runProc do
+        result = MSet.create ()
+        iter (Set.iter (MSet.add result)) sets
+        MSet.freeze result
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.runtime/scl/SetUtils.scl b/bundles/org.simantics.scl.runtime/scl/SetUtils.scl
deleted file mode 100644 (file)
index 00fa752..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-import "Prelude"
-import "Set" as Set
-import "MSet" as MSet
-import "MList" as MList
-
-fromList :: [a] -> Set.T a
-fromList l = runProc (MSet.freeze $ MSet.fromList l)
-
-toList :: Set.T a -> [a]
-toList s = runProc do
-    result = MList.createC (Set.size s)
-    Set.iter (MList.add result) s
-    MList.freeze result
\ No newline at end of file
index 7234b70be861c80806d752140cb575f5453b153c..e774f97466c7ffca313f5ed4b8284e3c12fe723a 100644 (file)
@@ -10,7 +10,7 @@ include "Lazy" as Lazy
 include "File" as File
 include "Serialization" as Serialization
 include "Set" as Set
-include "SetUtils" as Set
+include "SetClasses"
 //include "Map" as Map
 include "MMap" as MMap
 include "MSet" as MSet