Выпадающее меню 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..]])

Другие вопросы по тегам