根据数字用户输入构造反射的动态列表-dom widgets/events

Structuring a dynamic list of reflex-dom widgets/events according to numeric user input

我正在尝试创建一个动态的小部件列表,其中小部件的数量由用户输入的数值确定。此外,每个小部件 return 都是一个点击事件。这是我用来获取用户输入的内容:

settings :: MonadWidget t m => m (Dynamic t (Maybe Int))

然后我用它来生成一个随机数生成器列表(事实上这些是 RandomGen 的值并不重要。它们只是用于每个元素的内容,不是元素的个数。:

split' :: RandomGen g => Int -> g -> [g]
-- ...

gs <- mapDyn (maybe (split' 1 g) (flip split' g)) =<< settings

现在我有 gs :: (MonadWidget t m, RandomGen g) => Dynamic t [g]。每个小部件一个 g。这些小部件 return Event 值,因此我需要将它们组合起来(即 leftmost),然后将该值与 foldDyn 某处一起使用。

go :: (MonadWidget t m, Random g) => g -> m (Event t MyType)
-- ...

clicked <- el "div" $ do
  -- omg
  xs <- simpleList gs go

  -- would like to eventually do this
  dynEvent <- mapDyn leftmost xs
  return $ switch (current dynEvent)

但到目前为止我得到的结果是 xs :: Dynamic t [Dynamic t (m (Event t MyType))]

我认为我真正需要的是以某种方式制作 xs :: MonadWidget t m => Dynamic t [Event t MyType] 但即使使用 simpleList.

之外的其他功能也很难做到这一点

你的问题是 simpleList 需要 Dynamic t [g](Dynamic t g -> m a)。但是,您的目标是 g -> m (Event t MyType)。所以你需要创造一个更好的去:

go2 :: (MonadWidget t m, RandomGen g) => Dynamic t g -> m (Event t MyType)
go2 gDyn = do
    mapped <- mapDyn go gDyn
    dyned <- dyn mapped
    held <- hold never dyned
    return (switch held)

一旦你有了这个,它应该更容易,因为 simpleList gs go2 将 return m (Dynamic t [Event t MyType]) 并且你应该能够 mapDyn leftmost 超过它。

这不是最优雅的解决方案,但这是我在尝试类似解决方案时能够找到的最佳解决方案。我确定它可以提取到一些辅助函数中。

请注意,我没有随身携带编译器,并且在脑海中进行类型检查非常困难,所以如果它不起作用,请写评论。等我回家用编译器看看。