Haskell Netwire: Wire Harness

I play with the netwire package, trying to understand FRP, and I have a quick question.

Starting with the following simple wires, I can emit an event every 5 seconds (approximately)

myWire :: (Monad m, HasTime t s) => Wire s () m a Float
myWire = timeF

myWire' :: (Monad m, HasTime t s) => Wire s () m a Int
myWire' = fmap round myWire

myEvent :: (Monad m, HasTime t s) => Wire s () m a (Event Int)
myEvent = periodic 5 . myWire'

This is pretty nice and straight forward, but what I want to do next is to compare each event with the wiring, after which I can see the update. I have a battery function such as:

eventList :: (Monad m, HasTime t s) 
            => Wire s () m a (Event [Wire s () m a Int])
eventList = accumE go [] . myEvent
  where go soFar x = f x : soFar
        f x = for 10 . pure x --> pure 0

Then I introduce a new wire that will block until eventListit starts to fire events, for example:

myList :: (Monad m, HasTime t s) => Wire s () m a [Wire s () m a Int]
myList = asSoonAs . eventList

So, I switched from events to a wire containing a list of wires. Finally, I introduced a wire for each of these wires and compiled a list of results:

myNums :: (Monad m, HasTime t s) => Wire s () m [Wire s () m a Int] [Int]
myNums = mkGen $ \dt wires -> do
  stepped <- mapM (\w -> stepWire w dt $ Right undefined) wires
  let alive = [ (r, w) | (Right r, w) <- stepped ]
  return (Right (map fst alive), myNums)

myNumList :: (Monad m, HasTime t s) => Wire s () m a [Int]
myNumList = myNums . myList

And finally, I have my main procedure to check everything:

main = testWire clockSession_ myNumList

, , - , 10 , . . , , ,

[0]
[5, 0]
[10, 5, 0]
[15, 10, 0, 0]

..

[0]
[5, 0]
[10, 5, 0]
[15, 10, 5, 0]

, , : . , . for 10 . pure x --> pure 0 0 .

FRP, - (, .)

+4
2

, , , . Wire s e m a b , b a. Haskell , , , - stepWire, . myList:

Event 1: [for 10 . pure 0 --> pure 0]
Event 2: [for 10 . pure 5 --> pure 0, for 10 . pure 0 --> pure 0]
Event 3: [for 10 . pure 10 --> pure 0, for 10 . pure 5 --> pure 0, for 10 . pure 0 --> pure 0]
... etc

, [.., 10, 5, 0] , for 10 . pure x --> pure 0. stepWire:

stepWire :: Monad m => Wire s e m a b -> s -> Either e a -> m (Either e b, Wire s e m a b)

,

(result, w') <- stepWire w dt (Right underfined)

... w' stepWire, . , , -, .

, ( ) , , .

$ ghc -o test test.hs
[1 of 1] Compiling Main             ( test.hs, test.o )
Linking test ...
$ ./test
[0]
[5,0]
[10,5,0]
[15,10,0,0]
[20,15,0,0,0]
...
+2

, , , . , - , .

      [] -- we already know about
w0' : [] -- we got as input
w0' : [] -- what we should keep

, , , , .

            w2  : w1  : w0  : [] -- we already know about
w4' : w3' : w2' : w1' : w0' : [] -- we got as input
w4' : w3' : w2  : w1  : w0  : [] -- what we should keep

. . , .

makePrefixOf :: [a] -> [a] -> [a]
makePrefixOf [] ys = ys
makePrefixOf xs [] = xs
makePrefixOf (x:xs) (_:ys) = x:makePrefixOf xs ys

, . , - , .

makeSuffixOf :: [a] -> [a] -> [a]
makeSuffixOf xs ys = reverse $ makePrefixOf (reverse xs) (reverse ys)

myNums , oldWires .

myNums :: (Monad m, HasTime t s) => Wire s () m [Wire s () m a b] [b]
myNums = go []
  where
    go oldWires = mkGen $ \dt newWires -> do
        let wires = makeSuffixOf oldWires newWires
        stepped <- mapM (\w -> stepWire w dt $ Right undefined) wires
        let alive = [ (r, w) | (Right r, w) <- stepped ]
        return (Right (map fst alive), go (map snd alive))

, Maybe, , , Nothing, - . , , , . - , eventList.

            [ 0]
         [ 5, 0]
      [10, 5, 0]
   [15,10, 0, 0]
[20,15, 0, 0, 0]
+2

All Articles