Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I'm trying to create a dynamic list of widgets with the number of widgets determined by a numeric value from user input. Furthermore, each widget returns a click event. Here's what I'm using to get the user input:

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

Then I use this to generate a list of random number generators (The fact that these are values of RandomGen is not significant. They're just used for the content of each element, not the number of elements).:

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

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

Now I have gs :: (MonadWidget t m, RandomGen g) => Dynamic t [g]. One g for each widget. These widgets return Event values so I'll need to combine them (i.e. leftmost) then use that value with foldDyn somewhere.

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)

But so far I end up with xs :: Dynamic t [Dynamic t (m (Event t MyType))].

I think what I really need is to somehow make xs :: MonadWidget t m => Dynamic t [Event t MyType] instead but having some trouble getting there even with other functions aside from simpleList.

like image 287
James Avatar asked Oct 18 '22 13:10

James


1 Answers

Your problem is that simpleList takes a Dynamic t [g] and (Dynamic t g -> m a). However, your go is g -> m (Event t MyType). So you need to create a better go:

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)

Once you have this, it should be easier as simpleList gs go2 will return m (Dynamic t [Event t MyType]) and you should be able to mapDyn leftmost over it.

This is not the most elegant solution, but that's the best I was able to find when I was trying something similar. I'm sure it could be extracted into some helper function.

Note that I don't have a compiler with me, and typechecking this in my head is quite difficult, so if it doesn't work, write a comment. I'll have a look when I'm home with a compiler.

like image 82
Martin Kolinek Avatar answered Oct 21 '22 03:10

Martin Kolinek