Выпадающее меню Reflex, заполненное значениями типа суммы
Я следую этому руководству, из которого взят пример ниже: 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)
Я хочу заменить constDyn countries
из приведенного выше с помощью функции, которая принимает конструкторы типа (?) типа суммы и использует их в качестве элементов раскрывающегося списка.
Например, если у меня указан следующий тип суммы, я хочу, чтобы в раскрывающемся списке отображались "Тренировка" и "Бег". И если я позже добавлю, скажем,Solo_WatchPracticeTape
, раскрывающийся список автоматически добавит "Смотреть тренировочную ленту".
data SoloPersonPracticeType =
Solo_Workout
| Solo_Run
Я делаю вывод, что мне нужно создать функцию, которая связывает каждый тип суммы со строкой, а затем другую функцию, которая превращает все эти вещи во что-то проходимое, что может быть использовано constDyn
. Но я не вижу, как это реализовать.
РЕДАКТИРОВАТЬ:
Я пытаюсь это сделать, но это еще не закончено:
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..]
Но я все еще не понимаю, как это скармливать constDyn
в bodyElement
функция.
1 ответ
Такие классы, как Universe
а также Enum
как правило, инструмент, который вам нужен для этого. Фактически вам нужен способ создания списка из этих экземпляров, и это довольно просто:
[(e, show e) | e <- [minBound..]]
Вот show
предполагает, что у вашего типа есть Show
пример. Вы можете легко заменить это своей собственной "эффектной" вещью:
showMyType :: MyType -> Text
showMyType = \case
MyType_A -> "A"
MyType_B -> "B"
...
Наконец, все, что вам нужно, это передать весь этот список как Dynamic t (Map MyType Text)
к dropdown
как это: constDyn (Map.fromList [(e, showMyType e) | e <- [minBound..]])