@ 131018.10

131018.2 · 6a302f15b2ac2fa54f1db6e9788eb1e91a4e7501

update

reading declarations

Changes to Monads/. All files

Monads/Dot.hs

@@ -13,8 +13,12 @@ import Text.Printf (printf)  -- | @Node@ corresponds to any value representable as a Dot node. class Node a where+  -- | A uniquely identifying string for this node.   name :: a -> String-  label :: a -> Maybe String -- labels may not contain double quotes++  -- | Labels cannot contain double quotes. If no label is specified,+  -- then `name` will be used instead.+  label :: a -> Maybe String  -- | Every edge is a directed edge from one node to another. data Edge a = Edge { from :: a, to :: a, elabel :: Maybe String }@@ -26,9 +30,21 @@ instance Node SimpleNode where   name = sname   label = slabel +-- | Create a new @SimpleNode@ with a name.+simpleNode :: String -- ^ The name of the node.+              -> SimpleNode+simpleNode name = SimpleNode name Nothing +-- | Same as `simpleNode`, but allows a label independent of the name.+simpleNodeLabel :: String -- ^ The name of the node.+                   -> String -- ^ The label of the node.+                   -> SimpleNode+simpleNodeLabel name label = SimpleNode name (Just label)++-- | @Graph@ corresponds to a graph expressible in the Dot language. data Graph a = Graph { nodes :: [a], edges :: [Edge a] } +-- | Converts a graph to its Dot representation. dot :: Node a => Graph a -> String dot (Graph ns es) = printf "digraph G {\n\t%s\n\t%s\n}" nodes edges   where nodes = intercalate "\n\t" $ map dnode ns@@ -44,6 +60,7 @@ instance Monoid (Graph a) where   mempty = Graph [] []   (Graph ns1 es1) `mappend` (Graph ns2 es2) = Graph (ns1 ++ ns2) (es1 ++ es2) +-- | A monad that constructs values representable in the Dot language. newtype Dotter n a = Dotter { runDotter :: (a, Graph n) }  instance Monad (Dotter n) where@@ -51,30 +68,25 @@ instance Monad (Dotter n) where   Dotter (a, g) >>= f = Dotter (a', g `mappend` g')     where (a', g') = runDotter (f a) -simpleNode :: String -> SimpleNode-simpleNode name = SimpleNode name Nothing--simpleNodeLabel :: String -> String -> SimpleNode-simpleNodeLabel name label = SimpleNode name (Just label)-+-- | Adds a node to the current graph. addNode :: Node a => a -> Dotter a () addNode node = Dotter ((), Graph [node] []) -addEdge :: Node a => a -> a -> Dotter a ()+-- | Adds a directed edge to the current graph.+addEdge :: Node a+           => a -- ^ The "from" node.+           -> a -- ^ The "to" node.+           -> Dotter a () addEdge n1 n2 = Dotter ((), Graph [] [Edge n1 n2 Nothing]) -addEdgeLabel :: Node a => a -> a -> String -> Dotter a ()+-- | Same as `addEdge`, but with an edge label.+addEdgeLabel :: Node a+                => a -- ^ The "from" node.+                -> a -- ^ The "to" node.+                -> String -- ^ The edge label.+                -> Dotter a () addEdgeLabel n1 n2 label = Dotter ((), Graph [] [Edge n1 n2 (Just label)]) +-- | Evaluate an instance of the `Dotter` monad to its Dot representation. eval :: Node a => Dotter a () -> String eval = dot . snd . runDotter--testGraph :: Dotter SimpleNode ()-testGraph = do-  let (n1, n2) = (simpleNode "A", simpleNode "B")-  addNode n1-  addNode n2-  addEdge n1 n2--main :: IO ()-main = putStrLn $ eval testGraph

Monads/MRand.hs

@@ -6,6 +6,7 @@ where  import qualified System.Random as R +-- | A random monad that works with any generator satisfying `RandomGen`. newtype MRand g a = MRand (g -> (a, g))  instance R.RandomGen g => Monad (MRand g) where@@ -14,21 +15,31 @@ instance R.RandomGen g => Monad (MRand g) where                                     MRand m1 = f a                                  in m1 g') +-- | Evaluate an instance of the `MRand` monad with a source of randomness. eval :: R.RandomGen g => MRand g a -> g -> a eval (MRand f) g = fst (f g) +-- | Provides a random value. random :: (R.RandomGen g, R.Random a) => MRand g a random = MRand R.random -randomR :: (R.RandomGen g, R.Random a) => (a, a) -> MRand g a+-- | Provides a random value in a range.+randomR :: (R.RandomGen g, R.Random a)+           => (a, a) -- ^ An inclusive range [lo, hi].+           -> MRand g a randomR r = MRand (R.randomR r) +-- | Provides an infinite list of random values. randoms :: (R.RandomGen g, R.Random a) => MRand g [a] randoms = MRand (\g -> let (g', g'') = R.split g in (R.randoms g', g'')) -randomRs :: (R.RandomGen g, R.Random a) => (a, a) -> MRand g [a]+-- | Provides an infinite list of random values in a range.+randomRs :: (R.RandomGen g, R.Random a)+            => (a, a) -- ^ An inclusive range [lo, hi].+            -> MRand g [a] randomRs r = MRand (\g -> let (g', g'') = R.split g in (R.randomRs r g', g'')) +-- Demonstrates two infinite, independent sources of integers. two :: R.RandomGen g => MRand g ([Int], [Int]) two = do   xs <- randomRs (1, 10)@@ -40,4 +51,3 @@ main = do   let (xs, ys) = eval two g   print $ take 10 xs   print $ take 10 ys-