packages feed

SciFlow 0.1.0 → 0.2.0

raw patch · 4 files changed

+203/−33 lines, 4 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Scientific.Workflow.Builder: data Unit
- Scientific.Workflow.Builder: fromUnits :: [Unit] -> Graph
+ Scientific.Workflow.Builder: L4 :: (String, String, String, String) -> String -> Factor
+ Scientific.Workflow.Builder: L5 :: (String, String, String, String, String) -> String -> Factor
+ Scientific.Workflow.Builder: L6 :: (String, String, String, String, String, String) -> String -> Factor
+ Scientific.Workflow.Builder: data Factor
+ Scientific.Workflow.Builder: fromFactors :: [Factor] -> Graph
+ Scientific.Workflow.Builder: link1 :: String -> String -> Builder ()
+ Scientific.Workflow.Builder: link4 :: (String, String, String, String) -> String -> Builder ()
+ Scientific.Workflow.Builder: link5 :: (String, String, String, String, String) -> String -> Builder ()
+ Scientific.Workflow.Builder: link6 :: (String, String, String, String, String, String) -> String -> Builder ()
+ Scientific.Workflow.Builder: path :: [String] -> Builder ()
+ Scientific.Workflow.Types: zipS4 :: Source a -> Source b -> Source c -> Source d -> Source (a, b, c, d)
+ Scientific.Workflow.Types: zipS5 :: Source a -> Source b -> Source c -> Source d -> Source e -> Source (a, b, c, d, e)
+ Scientific.Workflow.Types: zipS6 :: Source a -> Source b -> Source c -> Source d -> Source e -> Source f -> Source (a, b, c, d, e, f)
- Scientific.Workflow.Builder: (~>) :: String -> String -> Builder ()
+ Scientific.Workflow.Builder: (~>) :: [String] -> String -> Builder ()
- Scientific.Workflow.Builder: B :: [(String, String, Text)] -> [(String, Unit)] -> B
+ Scientific.Workflow.Builder: B :: [(String, String, Text)] -> [(String, Factor)] -> B
- Scientific.Workflow.Builder: L :: String -> String -> Unit
+ Scientific.Workflow.Builder: L :: String -> String -> Factor
- Scientific.Workflow.Builder: L2 :: (String, String) -> String -> Unit
+ Scientific.Workflow.Builder: L2 :: (String, String) -> String -> Factor
- Scientific.Workflow.Builder: L3 :: (String, String, String) -> String -> Unit
+ Scientific.Workflow.Builder: L3 :: (String, String, String) -> String -> Factor
- Scientific.Workflow.Builder: S :: String -> Unit
+ Scientific.Workflow.Builder: S :: String -> Factor
- Scientific.Workflow.Builder: _links :: B -> [(String, Unit)]
+ Scientific.Workflow.Builder: _links :: B -> [(String, Factor)]
- Scientific.Workflow.Builder: link :: String -> String -> Builder ()
+ Scientific.Workflow.Builder: link :: [String] -> String -> Builder ()
- Scientific.Workflow.Builder.TH: linkNodes :: Unit -> HashMap String Unit -> Q Exp
+ Scientific.Workflow.Builder.TH: linkNodes :: Factor -> HashMap String Factor -> Q Exp

Files

SciFlow.cabal view
@@ -2,17 +2,67 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                SciFlow-version:             0.1.0+version:             0.2.0 synopsis:            Scientific workflow management system-description:         SciFlow is to help programmers design complex workflows-                     with ease.-                     .-                     Feature includes: -                     .-                        1. Use "labeled" arrows to connect individual steps-                           and cache computational results.-                        2. Use monad and template haskell to automate the process-                           of building DAGs.+description:+  SciFlow is to help programmers design complex workflows+  with ease.+  .+  Feature includes: +  .+  1. Use "labeled" arrows to connect individual steps+  and cache computational results.+  .+  2. Use monad and template haskell to automate the process+  of building DAGs.+  .+  Here is a trivial example. Since we use template haskell,+  we need to divide this small program into two files.+  .+  > -- File 1: MyModule.hs+  >+  > module MyModule where+  >+  > import Control.Arrow+  > import Scientific.Workflow+  >+  > input :: Actor () Int+  > input = arr $ const 10+  > +  > plus1 :: Actor Int Int+  > plus1 = arr (+1)+  >+  > mul2 :: Actor Int Int+  > mul2 = arr (*2)+  >+  > combine :: Actor (Int, Int) Int+  > combine = arr $ \(a,b) -> a + b+  >+  > -- builder monad+  > builder :: Builder ()+  > builder = do+  > node "id000" "input" "this is input"+  > node "id001" "plus1" "add 1 to the input"+  > node "id002" "mul2" "double the input"+  > node "id003" "combine" "combine two input"+  >+  > "id000" ~> "id001"+  > "id000" ~> "id002"+  > link2 ("id001", "id002") "id003"+  >+  > --------------------------------------------+  > -- File 2: main.hs+  >+  > import Scientific.Workflow+  > import MyModule+  > import Data.Default+  >+  > -- assemble workflow using template haskell+  > $(mkWorkflow "myWorkflow" builder)+  >+  > main = do result <- runWorkflow myWorkflow def+  >           print result+  .  license:             MIT license-file:        LICENSE
src/Scientific/Workflow/Builder.hs view
@@ -1,41 +1,78 @@+{-# LANGUAGE FlexibleInstances #-} module Scientific.Workflow.Builder where  import Control.Arrow (second)-import Control.Monad.State.Lazy (State, modify)+import Control.Monad.State.Lazy (State, modify, foldM_) import qualified Data.HashMap.Strict as M import qualified Data.Text as T import Data.Tuple (swap) -data Unit = S String-          | L String String-          | L2 (String,String) String-          | L3 (String,String,String) String+data Factor = S String+            | L String String+            | L2 (String,String) String+            | L3 (String,String,String) String+            | L4 (String,String,String,String) String+            | L5 (String,String,String,String,String) String+            | L6 (String,String,String,String,String,String) String  data B = B     { _nodes :: [(String, String, T.Text)]-    , _links :: [(String, Unit)]+    , _links :: [(String, Factor)]     }  type Builder = State B +-- | Declare a computational node node :: String -> String -> T.Text -> Builder () node l f anno = modify $ \s -> s{_nodes = (l,f,anno) : _nodes s} +-- | many-to-one generalized link function+link :: [String] -> String -> Builder ()+link [] t = singleton t+link [a] t = link1 a t+link [a,b] t = link2 (a,b) t+link [a,b,c] t = link3 (a,b,c) t+link [a,b,c,d] t = link4 (a,b,c,d) t+link [a,b,c,d,e] t = link5 (a,b,c,d,e) t+link [a,b,c,d,e,f] t = link6 (a,b,c,d,e,f) t+link _ _ = error "I can't have so many links, yet!"++-- | (~>) = link.+(~>) :: [String] -> String -> Builder ()+(~>) = link++-- | singleton singleton :: String -> Builder () singleton t = modify $ \s -> s{_links = (t, S t) : _links s} -link :: String -> String -> Builder ()-link a t = modify $ \s -> s{_links = (t, L a t) : _links s}+-- | Declare a path. +path :: [String] -> Builder ()+path ns = foldM_ f (head ns) $ tail ns+  where+    f a t = link1 a t >> return t -(~>) :: String -> String -> Builder ()-(~>) = link+-- | one-to-one link+link1 :: String -> String -> Builder ()+link1 a t = modify $ \s -> s{_links = (t, L a t) : _links s} +-- | two-to-one link link2 :: (String, String) -> String -> Builder () link2 (a,b) t = modify $ \s -> s{_links = (t, L2 (a,b) t) : _links s} +-- | tree-to-one link link3 :: (String, String, String) -> String -> Builder () link3 (a,b,c) t = modify $ \s -> s{_links = (t, L3 (a,b,c) t) : _links s} +link4 :: (String, String, String, String) -> String -> Builder ()+link4 (a,b,c,d) t = modify $ \s -> s{_links = (t, L4 (a,b,c,d) t) : _links s}++link5 :: (String, String, String, String, String) -> String -> Builder ()+link5 (a,b,c,d,e) t = modify $ \s -> s{_links = (t, L5 (a,b,c,d,e) t) : _links s}++link6 :: (String, String, String, String, String, String) -> String -> Builder ()+link6 (a,b,c,d,e,f) t = modify $ \s -> s{_links = (t, L6 (a,b,c,d,e,f) t) : _links s}++ data Graph = Graph     { _children :: M.HashMap String [String]     , _parents :: M.HashMap String [String]@@ -51,8 +88,8 @@ leaves :: Graph -> [String] leaves g = filter (\x -> null $ children x g) $ _vertice g -fromUnits :: [Unit] -> Graph-fromUnits us = Graph cs ps vs'+fromFactors :: [Factor] -> Graph+fromFactors us = Graph cs ps vs'   where     cs = M.fromListWith (++) $ map (second return) es'     ps = M.fromListWith (++) $ map (second return . swap) es'@@ -63,3 +100,6 @@     f (L a t) = ([a,t], [(a,t)])     f (L2 (a,b) t) = ([a,b,t], [(a,t),(b,t)])     f (L3 (a,b,c) t) = ([a,b,c,t], [(a,t),(b,t),(c,t)])+    f (L4 (a,b,c,d) t) = ([a,b,c,d,t], [(a,t),(b,t),(c,t),(d,t)])+    f (L5 (a,b,c,d,e) t) = ([a,b,c,d,e,t], [(a,t),(b,t),(c,t),(d,t),(e,t)])+    f (L6 (a,b,c,d,e,f) t) = ([a,b,c,d,e,f,t], [(a,t),(b,t),(c,t),(d,t),(e,t),(f,t)])
src/Scientific/Workflow/Builder/TH.hs view
@@ -18,7 +18,7 @@     return $ nodeDec ++ wfDec   where     builder = execState st $ B [] []-    endNodes = map (\x -> M.lookupDefault undefined x m) . leaves . fromUnits . snd . unzip . _links $ builder+    endNodes = map (\x -> M.lookupDefault undefined x m) . leaves . fromFactors . snd . unzip . _links $ builder     m = M.fromList $ _links builder     nd = map (\(a,b,_) -> (a,b)) $ _nodes builder @@ -29,17 +29,40 @@     f (l, ar) = [d| $(varP $ mkName l) = proc l $(varE $ mkName ar) |] {-# INLINE declareNodes #-} -linkNodes :: Unit -> M.HashMap String Unit -> Q Exp+linkNodes :: Factor -> M.HashMap String Factor -> Q Exp linkNodes nd m = [| Workflow $(go nd) |]   where     lookup' x = M.lookupDefault (S x) x m-    go (S a)          = varE $ mkName a-    go (L a t)        = [| $(go $ lookup' a) >>> $(go $ S t) |]-    go (L2 (a,b) t)   = [| zipS  $(go $ lookup' a) -                                 $(go $ lookup' b)-                             >>> $(go $ S t) |]-    go (L3 (a,b,c) t) = [| zipS3 $(go $ lookup' a)-                                 $(go $ lookup' b)-                                 $(go $ lookup' c)-                             >>> $(go $ S t) |]+    go (S a) = varE $ mkName a+    go (L a t) = [| $(go $ lookup' a) >>> $(go $ S t) |]+    go (L2 (a,b) t) =+        [| zipS  $(go $ lookup' a) +                 $(go $ lookup' b)+             >>> $(go $ S t) |]+    go (L3 (a,b,c) t) =+        [| zipS3 $(go $ lookup' a)+                 $(go $ lookup' b)+                 $(go $ lookup' c)+             >>> $(go $ S t) |]+    go (L4 (a,b,c,d) t) =+        [| zipS4 $(go $ lookup' a)+                 $(go $ lookup' b)+                 $(go $ lookup' c)+                 $(go $ lookup' d)+             >>> $(go $ S t) |]+    go (L5 (a,b,c,d,f) t) =+        [| zipS5 $(go $ lookup' a)+                 $(go $ lookup' b)+                 $(go $ lookup' c)+                 $(go $ lookup' d)+                 $(go $ lookup' f)+             >>> $(go $ S t) |]+    go (L6 (a,b,c,d,f,e) t) =+        [| zipS6 $(go $ lookup' a)+                 $(go $ lookup' b)+                 $(go $ lookup' c)+                 $(go $ lookup' d)+                 $(go $ lookup' f)+                 $(go $ lookup' e)+             >>> $(go $ S t) |] {-# INLINE linkNodes #-}
src/Scientific/Workflow/Types.hs view
@@ -91,6 +91,63 @@     c <- h ()     return (a,b,c) +zipS4 :: Source a+      -> Source b+      -> Source c+      -> Source d+      -> Source (a,b,c,d)+zipS4 (Processor f)+      (Processor g)+      (Processor h)+      (Processor i)+      = Processor $ \_ -> do+          a <- f ()+          b <- g ()+          c <- h ()+          d <- i ()+          return (a,b,c,d)++zipS5 :: Source a+      -> Source b+      -> Source c+      -> Source d+      -> Source e+      -> Source (a,b,c,d,e)+zipS5 (Processor f)+      (Processor g)+      (Processor h)+      (Processor i)+      (Processor j)+      = Processor $ \_ -> do+          a <- f ()+          b <- g ()+          c <- h ()+          d <- i ()+          e <- j ()+          return (a,b,c,d,e)++zipS6 :: Source a+      -> Source b+      -> Source c+      -> Source d+      -> Source e+      -> Source f+      -> Source (a,b,c,d,e,f)+zipS6 (Processor f)+      (Processor g)+      (Processor h)+      (Processor i)+      (Processor j)+      (Processor k)+      = Processor $ \_ -> do+          a <- f ()+          b <- g ()+          c <- h ()+          d <- i ()+          e <- j ()+          f <- k ()+          return (a,b,c,d,e,f)+ data Config = Config     { _baseDir :: !FilePath     }