diff options
Diffstat (limited to 'Control/Concurrent/Go.hs')
-rw-r--r-- | Control/Concurrent/Go.hs | 121 |
1 files changed, 60 insertions, 61 deletions
diff --git a/Control/Concurrent/Go.hs b/Control/Concurrent/Go.hs index 1bb0b86..08a1d65 100644 --- a/Control/Concurrent/Go.hs +++ b/Control/Concurrent/Go.hs @@ -1,45 +1,46 @@ -{- | An EDSL to make working with concurrent in-process code a bit easier - to read. - -This module is expected to be imported qualified as `Go`. Inspired by -Golang and Clojure's core.async. - -$example --} -{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE NoImplicitPrelude #-} + +-- | An EDSL to make working with concurrent in-process code a bit easier +-- to read. +-- +-- This module is expected to be imported qualified as `Go`. Inspired by +-- Golang and Clojure's core.async. +-- +-- \$example module Control.Concurrent.Go - ( - -- * Running and forking - fork - -- * Channels - , Channel - , chan - , read - , write - , mult - , tap + ( -- * Running and forking + fork, + + -- * Channels + Channel, + chan, + read, + write, + mult, + tap, ) where -import Alpha -import qualified Control.Concurrent as Concurrent -import qualified Control.Concurrent.Chan.Unagi.Bounded - as Chan -import qualified Data.Aeson as Aeson -import Data.Text ( Text ) -import qualified System.IO.Unsafe as Unsafe +import Alpha +import qualified Control.Concurrent as Concurrent +import qualified Control.Concurrent.Chan.Unagi.Bounded as Chan +import qualified Data.Aeson as Aeson +import Data.Text (Text) +import qualified System.IO.Unsafe as Unsafe -- | A standard channel. -data Channel a = Channel - { _in :: Chan.InChan a - , _out :: Chan.OutChan a - , _size :: Int - } +data Channel a + = Channel + { _in :: Chan.InChan a, + _out :: Chan.OutChan a, + _size :: Int + } instance Aeson.ToJSON (Channel a) where toJSON c = Aeson.String ("#<channel " <> len c <> ">" :: Text) - where len = show . Unsafe.unsafePerformIO . Chan.estimatedLength . _in + where + len = show . Unsafe.unsafePerformIO . Chan.estimatedLength . _in -- | Starts a background process. fork :: IO () -> IO Concurrent.ThreadId @@ -76,32 +77,30 @@ read = Chan.readChan . _out write :: Channel a -> a -> IO Bool write = Chan.tryWriteChan . _in -{- $example - -A simple example from ghci: - ->>> import qualified Control.Concurrent.Go as Go ->>> c <- Go.chan :: IO (Go.Channel Text) ->>> Go.write c "test" ->>> Go.read c -"test" - -An example with tap and mult: - ->>> c <- Go.chan :: IO (Go.Channel Text) ->>> Go.write c "hi" ->>> Go.read c -"hi" ->>> Go.fork ->>> Go.fork $ forever $ Go.mult c >>= Go.tap >>= \t -> print ("one: " <> t) -ThreadId 810 ->>> Go.fork $ forever $ Go.mult c >>= Go.tap >>= \t -> print ("two: " <> t) -ThreadId 825 ->>> Go.write c "test" -"two: t"eosnte": - test" - -The text is garbled because the actions are happening concurrently and -trying to serialize to write the output, but you get the idea. - --} +-- $example +-- +-- A simple example from ghci: +-- +-- >>> import qualified Control.Concurrent.Go as Go +-- >>> c <- Go.chan :: IO (Go.Channel Text) +-- >>> Go.write c "test" +-- >>> Go.read c +-- "test" +-- +-- An example with tap and mult: +-- +-- >>> c <- Go.chan :: IO (Go.Channel Text) +-- >>> Go.write c "hi" +-- >>> Go.read c +-- "hi" +-- >>> Go.fork +-- >>> Go.fork $ forever $ Go.mult c >>= Go.tap >>= \t -> print ("one: " <> t) +-- ThreadId 810 +-- >>> Go.fork $ forever $ Go.mult c >>= Go.tap >>= \t -> print ("two: " <> t) +-- ThreadId 825 +-- >>> Go.write c "test" +-- "two: t"eosnte": +-- test" +-- +-- The text is garbled because the actions are happening concurrently and +-- trying to serialize to write the output, but you get the idea. |