I am following this tutorial, from which the below example comes: https://github.com/hansroland/reflex-dom-inbits/blob/master/tutorial.md
bodyElement :: MonadWidget t m => m ()
bodyElement = el "div" $ do
el "h2" $ text "Dropdown"
text "Select country "
dd <- dropdown 2 (constDyn countries) def
el "p" $ return ()
let selItem = result <$> value dd
dynText selItem
countries :: Map.Map Int T.Text
countries = Map.fromList [(1, "France"), (2, "Switzerland"), (3, "Germany"), (4, "Italy"), (5, "USA")]
result :: Int -> T.Text
result key = "You selected: " <> fromJust (Map.lookup key countries)
I want replace constDyn countries
from the above with a function that takes the type (?) constructors of a sum type and uses them as the elements of the drop down.
For example, if I have the below sum type, I want the drop down to display "Workout" and "Run". And if I later add, say, Solo_WatchPracticeTape
, the dropdown would automatically add "Watch Practice Tape".
data SoloPersonPracticeType =
Solo_Workout
| Solo_Run
I infer that I need to make a function that associates each sum type with a string, then another function that turns all of those things into something traversable that can be taken in by constDyn
. But I do not see how to implement this.
EDIT:
I am trying this, but it is still unfinished:
displaySoloPersonPracticeType :: SoloPersonPracticeType -> [Char]
displaySoloPersonPracticeType Solo_Workout = "Workout"
displaySoloPersonPracticeType Solo_Run = "Run"
deriving instance Enum SoloPersonPracticeType
deriving instance Bounded SoloPersonPracticeType
instance Universe SoloPersonPracticeType where
universe = [minBound..]
But I still do not understand how to feed this into constDyn
in the bodyElement
function.
Classes like
Universe
andEnum
are generally the tool you want for this. You effectively want a way to generate a list from these instances and that's pretty easy:Here
show
presumes your type has aShow
instance. You could as easily replace that with your own custom "showy" thing:Finally, all you need is to pass this entire list as a
Dynamic t (Map MyType Text)
todropdown
like this:constDyn (Map.fromList [(e, showMyType e) | e <- [minBound..]])