haskell – 根据数字用户输入构建reflex-dom小部件/事件的动态列表

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

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)=>动态t [g].每个小部件一个g.这些小部件返回事件值,因此我需要将它们组合在一起(即最左边),然后将该值与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 =>相反,动态t [事件t MyType]但是除了simpleList之外还有其他功能.

最佳答案 你的问题是simpleList采用Dynamic t [g]和(Dynamic t g – > m a).但是,你的去g – > m(事件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将返回m(动态t [事件t MyType]),你应该能够在它上面最左边mapDyn.

这不是最优雅的解决方案,但这是我在尝试类似的东西时能够找到的最好的解决方案.我敢肯定它可以被提取到一些辅助函数中.

请注意,我没有编译器,并且在我的头脑中进行类型检查是非常困难的,所以如果它不起作用,请写一个注释.当我在家里使用编译器时,我会看看.

点赞