dynamic set of objects in netwire

Hey, I need (in netwire) a way to handle a dynamic set of objects. Therefor I need a way of growing and shrinking the set. Since I have little experience with Haskell and FRP, I would appreciate some input. Shrinking is not problem, as I can just remove wires that inhibit. But how to let the set grow? So far, my main loop would look like this: I have input data data Input = UpdatePhysic | KeyDown Int ... and the main Wire which creates objects on certain inputs and updates the physics when UpdatePhysics is send: mainWire :: WireP Input mainWire = proc input -> do userControlledObject <- userControlledObjectWire -< input if input == UpdatePhysics then do rec letCollData = ... physicsObjects <- physicsObjectsWire -< collData else empty -< My idea for the dynamics set wire is this: data Subwire e m a b = forall a'. Subwire (a -> a') (Wire e m a' b) dynamicSet :: (Monad m) => (c -> Subwire e m a b) -> Wire e m (Either a c) b The Idea is that the dynamicSet in every invocation either creates wires or steps them: mainWire :: WireP Input mainWire = proc input -> do userControlledObject <- userControlledObjectWire -< input rec let collisionData = ... objects <- dynamicSet -< if input == UpdatePhysics then Left collisionData else Right input So far so good, what bothers me is, that when I have several dynamicSets (different kind of objects) I have to make several if input == ... then ... else ... constructs, which feels repeative. I would welcome some input on how to structure the main loop and/or dynamic set... Regards, Nathan

Nathan Hüsken
I need (in netwire) a way to handle a dynamic set of objects. Therefor I need a way of growing and shrinking the set. Since I have little experience with Haskell and FRP, I would appreciate some input.
Shrinking is not problem, as I can just remove wires that inhibit. But how to let the set grow?
Originally the 4.0.0 release should include the manager wire, but I have long tried to come up with an interface that is generic enough to fit in as many situations as possible. The most obvious interface is through input. However, this really only works when only the user of the manager should be able to add or remove subwires. The interface is as simple as something like this: data MgrMsg k e m a b = Add k (Wire e m a b) | Delete k managerBasic :: (Monad m, Monoid b, Ord k) => Wire e m (a, [MgrMsg k e m a b]) b For many (if not most) applications the individual subwires should be allowed to control the current set of subwires as well, which is possible by adjusting the interface slightly and then using feedback: data MgrMsg k e m a b = Add k (Wire e m a (b, MgrMsg k e m a b)) | Delete k managerFeedback :: (Monad m, Monoid b, Ord k) => Wire e m (a, [MgrMsg k e m a b]) (b, [MgrMsg k e m a b]) Then you can use feedback: loop (managerFeedback . second (delay [])) This interface could fit your needs. However, in general there may also be the desire to have control over the current subwire set via the underlying monad, which is a very intriguing idea, because not only does that allow more efficiency without feedback, but it also allows the subwire set to be managed outside of the wire, even from another thread.
So far, my main loop would look like this: I have input data data Input = UpdatePhysic | KeyDown Int ...
and the main Wire which creates objects on certain inputs and updates the physics when UpdatePhysics is send:
You may be thinking too imperatively and/or too discretely here. Notice that FRP is about a continuous model. On its surface wires should always look like functions of time and input. In particular events should not discretely cut the input-output connection as they would do in your case:
The Idea is that the dynamicSet in every invocation either creates wires or steps them:
[...]
In other words: Don't think too much in terms of stepping/invocation. Actually in a perfect world FRP is so opaque that you totally forget about the underlying discrete time steps. =) Greets, Ertugrul -- Not to be or to be and (not to be or to be and (not to be or to be and (not to be or to be and ... that is the list monad.

On 11/07/2012 07:46 PM, Ertugrul Söylemez wrote:
Nathan Hüsken
wrote: I need (in netwire) a way to handle a dynamic set of objects. Therefor I need a way of growing and shrinking the set. Since I have little experience with Haskell and FRP, I would appreciate some input.
Shrinking is not problem, as I can just remove wires that inhibit. But how to let the set grow?
Originally the 4.0.0 release should include the manager wire, but I have long tried to come up with an interface that is generic enough to fit in as many situations as possible.
The most obvious interface is through input. However, this really only works when only the user of the manager should be able to add or remove subwires. The interface is as simple as something like this:
data MgrMsg k e m a b = Add k (Wire e m a b) | Delete k
managerBasic :: (Monad m, Monoid b, Ord k) => Wire e m (a, [MgrMsg k e m a b]) b
Mmh, how could you (form the outside) connect the output to the induvidual managed wires? Let's say I from one of the values in the output "b" I decide I want to delete the corresponding wire? I need to know the key "k". OK, I could encode "k" in the output but should I then not explicitly return "k" with it? Regards, Nathan

On 11/08/2012 06:58 PM, Nathan Hüsken wrote:
On 11/07/2012 07:46 PM, Ertugrul Söylemez wrote:
Nathan Hüsken
wrote: I need (in netwire) a way to handle a dynamic set of objects. Therefor I need a way of growing and shrinking the set. Since I have little experience with Haskell and FRP, I would appreciate some input.
Shrinking is not problem, as I can just remove wires that inhibit. But how to let the set grow?
Originally the 4.0.0 release should include the manager wire, but I have long tried to come up with an interface that is generic enough to fit in as many situations as possible.
The most obvious interface is through input. However, this really only works when only the user of the manager should be able to add or remove subwires. The interface is as simple as something like this:
data MgrMsg k e m a b = Add k (Wire e m a b) | Delete k
managerBasic :: (Monad m, Monoid b, Ord k) => Wire e m (a, [MgrMsg k e m a b]) b
Mmh, how could you (form the outside) connect the output to the induvidual managed wires? Let's say I from one of the values in the output "b" I decide I want to delete the corresponding wire? I need to know the key "k". OK, I could encode "k" in the output but should I then not explicitly return "k" with it?
Acually I am just realizing that I can "plumb" my wires so, that its output is (k,b) to get exactly this effect.

Nathan Hüsken
The most obvious interface is through input. However, this really only works when only the user of the manager should be able to add or remove subwires. The interface is as simple as something like this:
data MgrMsg k e m a b = Add k (Wire e m a b) | Delete k
managerBasic :: (Monad m, Monoid b, Ord k) => Wire e m (a, [MgrMsg k e m a b]) b
Mmh, how could you (form the outside) connect the output to the induvidual managed wires? Let's say I from one of the values in the output "b" I decide I want to delete the corresponding wire? I need to know the key "k". OK, I could encode "k" in the output but should I then not explicitly return "k" with it?
Acually I am just realizing that I can "plumb" my wires so, that its output is (k,b) to get exactly this effect.
This is a more general problem: How does a subwire /select/ a key for a new wire it wants to create? To most obvious answer is to use the underlying monad, which should be safe enough. Otherwise you can allow adding without a key and the corresponding subwire then gets the key fed back. Greets, Ertugrul -- Not to be or to be and (not to be or to be and (not to be or to be and (not to be or to be and ... that is the list monad.
participants (2)
-
Ertugrul Söylemez
-
Nathan Hüsken