úÎ=<    leon@melding-monads.com Safe-Infered  ReceivePorts3 represent the other end of a channel. A channel  can have many  ReceivePorts*, which all receive the same messages in  a publish/!subscribe like manner. A single  ReceivePort can be used F from multiple threads, where every message will be delivered to a  single thread in a push/pull like manner. Use  to fetch  messages from the channel.  SendPorts7 represent one end of the channel. There is only one  SendPort< per channel, though it can be used from multiple threads. - Messages can be sent to the channel using . Creates a new channel and a (SendPort, ReceivePort) pair representing ! the two sides of the channel. /Produces a new channel that initially has zero  ReceivePorts. ; Any elements written to this channel before a reader is ing , will be eligible for garbage collection.  Create a new  ReceivePort& attached the same channel as a given  SendPort. This  ReceivePort" starts out empty, and remains so * until more elements are written to the SendPort.  Create a new  ReceivePort) attached to the same channel as another   ReceivePort3. These two ports will receive the same messages. B Any messages in the channel that have not been consumed by the 3 existing port will also appear in the new port. IFetch an element from a channel. If no element is available, it blocks 2 until one is. Can be used in conjunction with System.Timeout. ISend an element to a channel. This is asynchronous and does not block. 3A right fold over a receiver, a generalization of getChanContents  where getChanContents = fold (:). Note that the type of  K implies that the folding function needs to be sufficienctly non-strict, . otherwise the result cannot be productive.  7 should usually be called only on readers that are not G subsequently used in other channel operations. Otherwise it may be D possible that the (non-)evaluation of pure values can cause race 1 conditions inside IO computations. The safer  uses   to avoid this issue. AAtomically send many messages at once. Note that this function M forces the spine of the list beforehand to minimize the critical section, M which also helps prevent exceptions at inopportune times. Trying to send M an infinite list will never send anything, though it will allocate a lot  of memory trying to do so. BThis function associates a brand new channel with a existing send D port, returning a new receive port associated with the existing F send port and a new send port associated with the existing receive  ports. IA possible use case is to transparently replace the backend of a service I without affecting the clients of that service. For example, we might % use it along the following lines:   * swapService :: SendPort Request -> IO ()  swapService s = do  (r', s') < - split s  send s' ShutdownRequest  forkNewService r' EThis is not a good solution in all cases. For example, the service D might consist of multiple threads, and maybe some of those send M internal messages on the same channel as the clients. It would probably G be a bug to change the destination that those internal messages go.  Wrapping the SendPort in  # would introduce an extra layer of I indirection, but also allows you to be selective about which senders 1 observe the effect. The clients would use an  (MVar (SendPort RequestOrInternalMessage) whereas the internal  threads would use the !SendPort RequestOrInternalMessage directly, # without going through the MVar.       leon@melding-monads.com Safe-Infered leon@melding-monads.com Safe-Infered          split-channel-0.1.1.0Control.Concurrent.Chan.Split,Control.Concurrent.Chan.Split.Implementation&Control.Concurrent.Chan.Split.Internal ReceivePortSendPortnew newSendPortlisten duplicatereceivesendfold unsafeFoldsendManysplitbaseGHC.MVarMVarItemList