2016-01-12 16 views
10

Так как натрий был deprecated автором Я пытаюсь передать свой код в реактивный банан. Тем не менее, кажется, что есть некоторые несоответствия между этими двумя, что я испытываю трудности с переполнением.Сэмплирование поведения из-за пределов сети

Например, натрий можно было легко получить текущее значение поведения:

retrieve :: Behaviour a -> IO a 
retrieve b = sync $ sample b 

Я не вижу, как это сделать в реакционно-банане

(причиной я хочу это потому, что я пытаюсь экспортировать поведение как свойство Dbus свойства могут быть запрошены от других клиентов Dbus)

Edit:. Заменил слово «опрос», как это вводит в заблуждение

+0

На концептуальном уровне дискретизации 'Behavior' имеет смысл только в контексте' Moment', то есть в конкретной момент времени, который 'IO' не предоставляет. Это не просто теоретическая проблема, но важна для внутренней согласованности реализации, поэтому я не решаюсь добавить такую ​​функцию. Не могли бы вы рассказать о конкретном контексте, в котором вы хотите использовать это (dbus)? Скорее всего, это можно выразить по-другому. –

+0

Я устанавливаю функцию обратного вызова (getCurrentState :: IO Response) при создании свойства, которое вызывается при получении запроса. Указанная функция обратного вызова должна каким-то образом восстановить текущее значение Поведения (предположительно используя то же понятие «текущий» или «сейчас» как запуск события, вызвав функцию обработчика, созданную newAddHandler). – Philonous

+1

Оказывается, я могу повторно реализовать такое же поведение с инструментами реактивного банана: [gist] (https://gist.github.com/b334c81018628fd6cfc8).Я использую unsafePerformIO в этом примере, чтобы как можно ближе подойти к семантике натрия, но это отнюдь не обязательно (мне просто нужно было бы выполнить действие IO). Поэтому возникает вопрос: есть ли причина не строить сеть с повторными «выполнением», а не напрямую с компиляцией? – Philonous

ответ

0

Ответ, кажется, "это своего рода возможно".

sample соответствует valueB, но нет прямого эквивалента sync.

Однако он может быть повторно реализован с помощью execute:

module Sync where 

import Control.Monad.Trans 
import Data.IORef 
import Reactive.Banana 
import Reactive.Banana.Frameworks 

data Network = Network { eventNetwork :: EventNetwork 
         , run :: MomentIO() -> IO() 
         } 

newNet :: IO Network 
newNet = do 
    -- Create a new Event to handle MomentIO actions to be executed 
    (ah, call) <- newAddHandler 
    network <- compile $ do 
     globalExecuteEV <- fromAddHandler ah 
     -- Set it up so it executes MomentIO actions passed to it 
     _ <- execute globalExecuteEV 
     return() 
    actuate network 
    return $ Network { eventNetwork = network 
        , run = call -- IO Action to fire the event 
        } 

-- To run a MomentIO action within the context of the network, pass it to the 
-- event. 
sync :: Network -> MomentIO a -> IO a 
sync Network{run = call} f = do 
    -- To retrieve the result of the action we set up an IORef 
    ref <- newIORef (error "Network hasn't written result to ref") 
    -- (`call' passes the do-block to the event) 
    call $ do 
     res <- f 
     -- Put the result into the IORef 
     liftIO $ writeIORef ref res 
    -- and read it back once the event has finished firing 
    readIORef ref 

-- Example 
main :: IO() 
main = do 
    net <- newNet -- Create an empty network 
    (bhv1, set1) <- sync net $ newBehavior (0 :: Integer) 
    (bhv2, set2) <- sync net $ newBehavior (0 :: Integer) 
    set1 3 
    set2 7 
    let sumB = (liftA2 (+) bhv1 bhv2) 
    print =<< sync net (valueB sumB) 
    set1 5 
    print =<< sync net (valueB sumB) 
    return() 
0

Для концептуальных/архитектурных причин, Reactive Banana имеет функции от Event до Behavior, но не наоборот, и это тоже имеет смысл, учитывая природу и значение FRP. Я уверен, что вы можете написать функцию опроса, но вместо этого вам следует рассмотреть возможность изменения базового кода, чтобы вместо этого отображать события.

Есть ли причина, по которой вы не можете изменить свой Behavior в Event? Если нет, это будет хороший способ решить вашу проблему. (Возможно, теоретически даже покажет недостаток дизайна, о котором вы не заметили до сих пор.)

+0

Я не уверен, как это относится к моему вопросу. Я уверен, что это должно быть Поведение, поскольку оно моделирует изменяющееся во времени значение. Моя проблема в том, что у меня есть запрос, поступающий из сети, на который я хотел бы ответить с текущим значением этого поведения. Конечно, я мог бы моделировать прибытие этого запроса в качестве события (путем запуска обработчика), но это только получит запрос в сеть (frp-), он не сможет получить результат для отправки назад. – Philonous

+0

Мой выбор слова «опрос», возможно, вводит в заблуждение. Я не хочу проверять, когда значение изменилось, скорее я хотел бы получить значение Поведения в определенное время, например. ответить на сетевой запрос (думаю, HTTP) – Philonous

+0

О, я вижу, мой плохой тогда :) –

1

Если у вас есть поведение, моделирующее значение вашего свойства, и у вас есть событие, моделирующее входящие запросы для значения свойства, то вы может просто использовать (<@) :: Behavior b -> Event a -> Event b , чтобы получить новое событие, происходящее во время входящих запросов, с значением, которое имеет свойство в то время). Затем вы можете преобразовать это в действительные действия ввода-вывода, которые необходимо предпринять, чтобы ответить на запрос, и использовать как обычно reactimate.


https://hackage.haskell.org/package/reactive-banana-1.1.0.0/docs/Reactive-Banana-Combinators.html#v:-60--64-

+0

Нет ответа для ответа на запрос, вместо этого возвращается ответное значение набора обратных вызовов для свойства dbus.То, что я могу сделать, это создать новый IORef и передать в Событие вместе с запросом, использовать реактив, чтобы поместить дискретированное значение в IORef, а затем прочитать IORef в функции обработки запроса после возврата вызова Event. Однако для этого требуется взаимодействующий код в двух местах (сеть событий и функция обратного вызова), что делает код сложнее поддерживать, по сравнению с простым решением, которое дает натрий. – Philonous

 Смежные вопросы

  • Нет связанных вопросов^_^