Haskell Netwire: Wire Harnesses Correct

I am trying to implement the dynamic wire set in netwire 5 "correctly." I read the answer to the question of wire wires , and I don’t really like how the code in the example relies on Event, converted to behavior, to display not empty only with one execution stepWire.

So, I want to add and remove wires in a dynamic set using Events, and hopefully without clicking on Unsafe.Eventor an equivalent hacker. Leave the deletion part for simplicity and just add Wires:

dynWireSet1 :: (Monad m, Monoid s)
            => Wire s e m (a, Event (Wire s e m a b)) [b]

Each event adds a new wire to the (initially empty) list (or other set) of wires hidden inside, and they all fire, they all receive type input a, and their outputs are collected in a list.

The working part is relatively simple, with googleable examples, for example:

dynWireSet1 = runWires1 []
runWires1 :: (Monad m, Monoid s)
          => [Wire s e m a b]
          -> Wire s e m (a, Event (Wire s e m a b)) [b]
runWires1 wires = mkGen $ \session (input, event) -> do
  stepped <- mapM (\w -> stepWire w session (Right input)) wires
  let (outputs, newwires) = unzip stepped
  return (sequence outputs, runWires1 newwires)

The example above ignores events. I suspect that it is not possible to use the event inside the transition function except Eventfrom Unsafe.Event. It's right? I want to avoid Unsafe.Event.

When I step back and look at the suggested ways to use events, I see a function that looks very promising:

krSwitch :: Monad m
         => Wire s e m a b
         -> Wire s e m (a, Event (Wire s e m a b -> Wire s e m a b)) b

Now, if I start with simplified runWires:

runWires2 :: (Monad m, Monoid s)
          => [Wire s e m a b]
          -> Wire s e m a [b]
runWires2 wires = mkGen $ \session input -> do
  stepped <- mapM (\w -> stepWire w session (Right input)) wires
  let (outputs, newwires) = unzip stepped
  return (sequence outputs, runWires2 newwires)

and make dynWireSet krSwitch:

dynWireSet2 :: (Monad m, Monoid s)
            => Wire s e m (a, Event (Wire s e m a b)) [b]
dynWireSet2 = krSwitch (runWires2 []) . second (mkSF_ (fmap addWire))
addWire :: Wire s e m a b -> Wire s e m a [b] -> Wire s e m a [b]
addWire = undefined

! , fmap a (:) runWires2 , newwires, ! , . , fmap WGen fmaps , . .

, . data Wire, WCarry g st, .

((a, c) -> m (b, c))

, , Wire :

mkCarry :: Monad m => ((a, c) -> m (b, c)) -> c -> Wire s e m a b
mkCarry transfun state = mkGenN $ \input -> do
  (output, newstate) <- transfun (input, state)
  return (Right output, mkCarry transfun newstate)

WCarry WGen . runWires mkCarry.

fmap :

fmap f (WCarry g st) = WCarry g (fmap f st)

It will change the state object "hidden inside", and we can use the function krSwitchfor this type Wires to adjust the internal state without losing the previous value.

It makes sense? If what I'm trying to do is possibly in a simpler way, I advise! If what I'm talking about makes sense, how can I do this? Is it possible to locally expand the definition data Wireusing WCarry and expand the addition of interesting class instances with the corresponding definitions? Any other tips?

Thanks.

+4
source share
1 answer

Netwire, , , , . , () - . WCarry, .

. , addWire , "" . subwire, , :

addWire w ws = fmap (uncurry (:)) (w &&& ws)

, . , !

+2

Source: https://habr.com/ru/post/1611642/


All Articles