5

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

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每个小部件一个。这些小部件返回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.

4

1 回答 1

3

你的问题是 simpleList 需要一个Dynamic t [g]and (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返回m (Dynamic t [Event t MyType]),你应该能够mapDyn leftmost克服它。

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

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

于 2016-04-08T11:12:04.857 回答