1

我的具体问题是这样的:

给定 anEvent t [a]和 an Event t ()(假设它是一个滴答事件),我想生成一个Event t a,即一个事件,它为每次发生滴答事件提供输入列表中的连续项目。

Reflex 有以下助手:

zipListWithEvent :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> c) -> [a] -> Event t b -> m (Event t c)

这正是我想要的,但不将事件作为输入,而只是一个列表。鉴于我有一个Event t [a],我认为我可以产生一个包含事件的事件并只是切换,但问题是它zipListWithEven在单子上下文中运行,因此我可以得到:

Event t (m (Event t a))

这是switch原始人不接受的东西。

现在,也许我以错误的方式接近它,所以这是我的一般问题。给定一个生成坐标列表和刻度事件的事件,我想生成一个可以“使用”沿坐标移动对象的事件。因此,每次触发滴答声时,都会更新位置。每次我更新坐标列表时,它都会开始从该新列表中生成位置。

4

2 回答 2

1

我不完全确定我是否正确理解了所需函数的语义,但在反应香蕉库中,我会解决这样的问题:

trickle :: MonadMoment m => Event [a] -> Event () -> Event a
trickle eadd etick = do
    bitems <- accumB [] $ unions    -- 1
        [ flip (++) <$> eadd        -- 2
        , drop 1    <$  etick       -- 3
        ]
    return $ head <$> filterE (not . null) (bitems <@ etick) -- 4

该代码的工作原理如下:

  1. 行为bitems记录当前的项目列表。
  2. 发生时添加项目eadd,...
  3. etick...并且在发生时会删除一项。
  4. 结果是无论何时etick发生都会发生的事件,并且只要该列表非空,就会包含(先前)当前列表的第一个元素。

这个解决方案似乎不需要任何花哨或复杂的推理。

于 2016-11-27T09:19:43.043 回答
1

命名零件:

coords :: Event t [Coord]
ticks  :: Event t ()

如果我们想记住最近Coord的直到下一次触发ticks,那么我们必须在 some monadReflex m中。这是允许瞬态Event持久化的 monad。

您要记住的核心内容是一堆Coord. 让我们试试这个:

data Stack a = CS {
    cs_lastPop :: Maybe a
  , cs_stack   :: [a]
  } deriving (Show)

stack0 = CS Nothing []

pop :: Stack a -> Stack a
pop (CS _ []    ) = CS Nothing []
pop (CS _ (x:xs)) = CS (Just x) xs

reset :: [a] -> Stack a -> Stack a
reset cs (CS l _) = CS l cs

那里还没有任何反应,两个功能可以Stack Coord按照您在问题中提到的方式进行调整。

驱动它的反射代码将Dynamic t (Stack Coord)通过指定它的初始状态和所有修改它的东西来构建一个:

  coordStack <- foldDyn ($) stack0 (leftmost [
      reset <$> coords
    , pop   <$  ticks
    ])

这里leftmost需要一个Stack Coord -> Stack Coord函数列表,这些函数依次应用于stack0by foldDyn ($) (只要coords并且ticks永远不会出现在同一帧中)

驾驶这一切main

main :: IO ()
main = mainWidget $ do
  t0 <- liftIO getCurrentTime

  -- Some make up 'coords' data, pretending (Coord ~ Char)
  coordTimes <- tickLossy 2.5 t0
  coords <- zipListWithEvent (\c _ -> c) ["greg","TOAST"] coordTimes

  ticks <- tickLossy 1 t0

  coordStack <- foldDyn ($) stack0 (leftmost [
      reset <$> coords
    , pop   <$  ticks
    ])

  display coordStack
于 2017-03-05T23:31:13.693 回答