summaryrefslogtreecommitdiff
path: root/src/Control/Funflow/Diagram.hs
blob: 958191160ce13a2eb4c56a94435dfd314f090e8a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE GADTs                 #-}
{-# LANGUAGE InstanceSigs          #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables   #-}
-- | A Diagram is a representation of an arrow with labels.
--   No computation is actually performed by a diagram, it just carries
--   around a description.
--   We explot the fact that in 7.10,
--   everything is typeable to label the incoming and outgoing node types.
module Control.Funflow.Diagram where

import           Control.Arrow
import           Control.Arrow.Free (ArrowError (..))
import           Control.Category
import           Data.Proxy         (Proxy (..))
import qualified Data.Text          as T
import           Prelude            hiding (id, (.))


newtype NodeProperties = NodeProperties {
  labels :: [T.Text]
}

emptyNodeProperties :: NodeProperties
emptyNodeProperties = NodeProperties []

data Diagram ex a b where
  Node :: NodeProperties
       -> Proxy a
       -> Proxy b
       -> Diagram ex a b
  Seq :: Diagram ex a b -> Diagram ex b c -> Diagram ex a c
  Par :: Diagram ex a b -> Diagram ex c d -> Diagram ex (a,c) (b,d)
  Fanin :: Diagram ex a c -> Diagram ex b c -> Diagram ex (Either a b) c
  Catch   :: Diagram ex a b -> Diagram ex (a,ex) b -> Diagram ex a b

instance Category (Diagram ex) where
  id = Node emptyNodeProperties Proxy Proxy
  (.) = flip Seq

instance Arrow (Diagram ex) where
  arr :: forall a b. (a -> b) -> Diagram ex a b
  arr = const $ Node emptyNodeProperties (Proxy :: Proxy a) (Proxy :: Proxy b)
  first f = Par f id
  second f = Par id f
  (***) = Par

instance ArrowChoice (Diagram ex) where
  f +++ g = (f >>> arr Left) ||| (g >>> arr Right)
  f ||| g = Fanin f g

instance ArrowError ex (Diagram ex) where
  f `catch` g = Catch f g

-- | Construct a labelled node
node :: forall arr a b ex. Arrow arr => arr a b -> [T.Text] -> (Diagram ex) a b
node _ lbls = Node props (Proxy :: Proxy a) (Proxy :: Proxy b)
  where props = NodeProperties lbls