由总和类型值填充的反射下拉菜单
Reflex dropdown menu populated by sum type values
我正在学习本教程,以下示例来自该教程: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
,该函数采用求和类型的类型 (?) 构造函数并将它们用作下拉列表的元素。
例如,如果我有以下总和类型,我希望下拉列表显示 "Workout" 和 "Run"。如果我稍后添加 Solo_WatchPracticeTape
,下拉列表将自动添加 "Watch Practice Tape".
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..]
但我仍然不明白如何将其输入 bodyElement
函数中的 constDyn
。
类 就像 Universe
和 Enum
通常是您想要的工具。您实际上想要一种从这些实例生成列表的方法,这非常简单:
[(e, show e) | e <- [minBound..]]
这里 show
假定您的类型有一个 Show
实例。您可以轻松地将其替换为您自己的自定义 "showy" 东西:
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..]])
我正在学习本教程,以下示例来自该教程: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
,该函数采用求和类型的类型 (?) 构造函数并将它们用作下拉列表的元素。
例如,如果我有以下总和类型,我希望下拉列表显示 "Workout" 和 "Run"。如果我稍后添加 Solo_WatchPracticeTape
,下拉列表将自动添加 "Watch Practice Tape".
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..]
但我仍然不明白如何将其输入 bodyElement
函数中的 constDyn
。
类 就像 Universe
和 Enum
通常是您想要的工具。您实际上想要一种从这些实例生成列表的方法,这非常简单:
[(e, show e) | e <- [minBound..]]
这里 show
假定您的类型有一个 Show
实例。您可以轻松地将其替换为您自己的自定义 "showy" 东西:
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..]])