19 Jun 17:17 2014

## Do you recognize this type?

Corentin Dupont <corentin.dupont <at> gmail.com>

2014-06-19 15:17:13 GMT

2014-06-19 15:17:13 GMT

Hi guys,

I am making a DSL for event composition (inspired from digestive-functor & reactive-banana) and I find myself wanting a primitive like that:

-- given a list of events, evaluate the function on those that have already fired.

-- returns an event yelding the result when ready.

ListEvent :: [Event a] -> ([a] -> Maybe b) -> Event b

Does this type tell you something? Is there a better abstraction that can encompass it?-- given a list of events, evaluate the function on those that have already fired.

-- returns an event yelding the result when ready.

ListEvent :: [Event a] -> ([a] -> Maybe b) -> Event b

My DSL is like that:

-- | Composable events

data Event a where

SumEvent :: Event a -> Event a -> Event a -- The first event to fire will be returned

AppEvent :: Event (a -> b) -> Event a -> Event b -- Both events should fire, and then the result is returned

PureEvent :: a -> Event a -- Create a fake event. The result is useable with no delay.

EmptyEvent :: Event a -- An event that is never fired.

BaseEvent :: (Typeable a) => Field a -> Event a -- Embed a base event

data Event a where

SumEvent :: Event a -> Event a -> Event a -- The first event to fire will be returned

AppEvent :: Event (a -> b) -> Event a -> Event b -- Both events should fire, and then the result is returned

PureEvent :: a -> Event a -- Create a fake event. The result is useable with no delay.

EmptyEvent :: Event a -- An event that is never fired.

BaseEvent :: (Typeable a) => Field a -> Event a -- Embed a base event

It's easy to define instances for Applicative and Alternative.

But then I have a use case that I cannot solve:

In the case of votations (which use this DSL), sometime you can end prematuraly the voting, even if not everybody voted yet: for example if the majority is already reached.

In this case no need to wait for everybody, we can end the vote.

This does not seem to be possible with Applicative or Monad interfaces: things have to be sequenced in a monad, they cannot be evaluated in parralel.

For example:

do

v1 <- getVote1

v2 <- getVote2

v3 <- getVote3

evalMajority(v1, v2, v3)

In this example I have to wait for all 3 votes to be completed, but in fact only two would suffice to achieve majority.

That's why I added "ListEvent" to the DSL above which allow to achieve that but I'm wondering if there is a better/bigger abstraction to put it in.

Thanks!!

Corentin

_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe <at> haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe