<div dir="ltr">Hi Rouan,<div><br></div><div>I like how a similar concept is implemented in F# and I did a similar Signal type in my simulation library Aivika [1]. Only in my case the signals (events) are bound up with the modeling time.</div>
<div><br></div><div>The publish function can be indeed and should be pure. Moreover, I personally preferred the IObservable concept above the Event one as the former seems to be more functional-like.</div><div><br></div><div>
Just in F# they introduce also the event source and treat the events and their sources differently. Therefore, the publish function, being defined for the event source, is pure.</div><div><br></div><div>Thanks,</div><div>
David</div><div><br></div><div>[1] <a href="http://hackage.haskell.org/package/aivika">http://hackage.haskell.org/package/aivika</a></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Mar 28, 2014 at 2:59 PM, Rouan van Dalen <span dir="ltr"><<a href="mailto:rvdalen@yahoo.co.uk" target="_blank">rvdalen@yahoo.co.uk</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Cafe,<br>
<br>
I am trying to write a very simple implementation of an event publisher pattern but I am stuck and do<br>
not know how to do this in Haskell.<br>
<br>
I have the following code:<br>
<br>
========================<br>
<br>
<br>
{-# LANGUAGE RankNTypes, NamedFieldPuns #-}<br>
<br>
module Domain.DomainEventPublisher where<br>
<br>
   import Control.Monad (forM_)<br>
<br>
   import HsFu.Data.DateTime<br>
   import Domain.Client<br>
<br>
<br>
   data DomainEvent = ClientChangeAgeDomainEvent<br>
<br>
<br>
   data DomainEventContext =<br>
      DomainEventContext { domainEventContext_event      :: DomainEvent<br>
                         , domainEventContext_occurredOn :: DateTime<br>
                         } deriving (Show)<br>
<br>
<br>
   data DomainEventPublisher = DomainEventPublisher { domainEventPublisher_subscribers :: [DomainEventContext -> IO ()] }<br>
<br>
<br>
   mkEventPublisher :: DomainEventPublisher<br>
   mkEventPublisher = DomainEventPublisher []<br>
<br>
<br>
   subscribe :: DomainEventPublisher -> (DomainEventContext -> IO ()) -> DomainEventPublisher<br>
   subscribe publisher eventHandler =<br>
      DomainEventPublisher { domainEventPublisher_subscribers = eventHandler : (domainEventPublisher_subscribers publisher) }<br>
<br>
<br>
   publish :: DomainEventPublisher -> DomainEventContext -> IO ()<br>
   publish DomainEventPublisher{ domainEventPublisher_subscribers } event =<br>
      forM_ domainEventPublisher_subscribers ($ event)<br>
<br>
========================<br>
<br>
<br>
My problem is that the publish method returns IO (), which means that events can only be<br>
published from the IO monad, but I would like events to be 'publish-able' from pure code.<br>
<br>
I can live with event handlers (passed into the subscribe function) being in the IO monad.<br>
<br>
Is there a better way to implement this pattern in Haskell?<br>
<br>
I have been racking my brain on this for a while now and cannot seem to come up with a<br>
good implementation.<br>
<br>
Regards<br>
--Rouan.<br>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
</blockquote></div><br></div>