У меня есть поведение, значение которого я хочу изменить в зависимости от возникновения события и текущего значения поведения. В приведенном ниже примере у меня есть два счетчика, которые обновляются в зависимости от того, является ли логическое поведение истинным или ложным. Так как этот код дает сбой с исключением <<loop>>
, но я не уверен, как реструктурировать его для работы или как еще решить эту проблему.
{-# LANGUAGE ScopedTypeVariables #-}
import Reactive.Banana
import Reactive.Banana.Frameworks
import Control.Arrow
import Control.Concurrent
import Control.Monad
import Control.Monad.Fix
counter :: Bool -> Event t Int -> Behavior t Bool -> (Behavior t Int, Event t (Bool -> Bool))
counter b input active = (result, whenE ((b/=) <$> active) (fmap (const not) input))
where result = accumB 0 (fmap (+) evt')
evt' = whenE ((b==) <$> active) input
alternater :: Event t Int -> Behavior t Bool -> (Behavior t (Bool, (Int, Int)), Event t (Bool -> Bool))
alternater input active = ((,) <$> active <*> ((,) <$> fst t1 <*> fst t2), snd t1 `union` snd t2)
where t1 = counter True input active
t2 = counter False input active
main :: IO ()
main = do
(inputHandler, fireInput) <- newAddHandler
let network :: forall t . Frameworks t => Moment t ()
network = do
eInput <- fromAddHandler inputHandler
let ui :: Behavior t (Bool, (Int, Int)) -> Moment t (Behavior t (Bool, (Int, Int)))
ui b = do
let (behavior, evt) = alternater eInput (fst <$> b)
return $ stepper id (fmap (***id) evt) <*> behavior
output <- changes =<< mfix ui
reactimate $ putStrLn . show <$> output
forkIO $ actuate =<< compile network
forever $ getLine >>= fireInput . read
accumB
для вычисленияresult
, поэтому я думаю, чтоbehavior
(внутриui
), вероятно, подойдет. Я подозреваю, что проблема вevt
.evt
также зависит отb
, но для его вычисления не используются отсроченные или наблюдаемые примитивы. К сожалению, на данный момент у меня нет ни малейшего представления о том, что вы должны сделать, чтобы это исправить. - person Jason Dagit   schedule 14.07.2013behavior
находится внутриui
, вот в чем проблема, потому что, когда я удаляю ссылку на evt (превращая ее вreturn $ stepper id (fmap (***id) never) <*> behavior
), я все равно сталкиваюсь с ‹‹loop››. - person merijn   schedule 14.07.2013accumB
должен быть наблюдаемым. То же самое сstepper
. - person Jason Dagit   schedule 14.07.2013