나는 행동 값과 행동의 현재 값에 따라 값을 바꾸고 싶은 행동이있다. 아래 예제에서는 부울 동작이 True인지 False인지에 따라 업데이트되는 두 개의 카운터가 있습니다. 이 코드가 <<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'에 의존하지만, 그것을 계산하는 데 사용되는 지연되거나 관찰 가능한 원시 요소가 없습니다. 불행히도, 나는 그 순간에 당신이 그것을 고치기 위해 무엇을해야만하는지 가장 안 좋은 생각이 없습니다. –
사실,'evi (return $ stepper id (fmap (*** id) never) <*> 동작'으로 바꾸면 evt에 대한 참조를 제거 할 때 문제가되는'ui' 내부의' 나는 여전히 <>을 만나고 있습니다. –
merijn
흠 ...이 경우 버그 일 수 있습니까? 문서에서는 'accumB'가 관찰 가능하다고 가정합니다. '스테퍼 '와 동일합니다. –