Список флажков с пищеварительными функторами
Как использовать пищеварительные функторы для создания формы, которая имеет программно сгенерированный список флажков, который возвращает список. Например:
[x] Milk
[ ] Cereals
[x] Ground meat
вернется ["Milk", "Ground meat"]
,
Я ожидаю, что тип будет что-то вроде:
form :: (Functor m, Monad m) => [String] -> HappstackForm m Html BlazeFormHtml [String]
1 ответ
Решение
Нет стандартного способа сделать это, но digestive-functors
с высокой степенью композита, используя Applicative
интерфейс, так что вы можете легко создать то, что вы хотите.
Вы можете определить checkBox
который возвращает Maybe String
имя элемента, если он был проверен.
checkBox :: (Functor m, Monad m)
=> String -> HappstackForm m Html BlazeFormHtml (Maybe String)
checkBox str = fmap maybeStr (inputCheckBox False) <++ label str
where
maybeStr True = Just str
maybeStr False = Nothing
Затем вы можете перебрать список строк, чтобы создать флажок, подобный этому, для каждого элемента в списке:
listForm' :: (Functor m, Monad m)
=> [String]
-> HappstackForm m Html BlazeFormHtml [Maybe String]
listForm' = foldr (\x xs -> fmap (:) x <*> xs) (pure []) . map checkBox
catMaybes :: [Maybe a] -> [a]
поможет вам уменьшить результат в дальнейшем:
listForm :: (Functor m, Monad m)
=> [String]
-> HappstackForm m Html BlazeFormHtml [String]
listForm = fmap catMaybes . listForm'
И, наконец, мы можем создать экземпляр фактической формы:
food :: [String]
food = ["Milk", "Cereals", "Ground meat"]
foodForm :: (Functor m, Monad m)
=> HappstackForm m Html BlazeFormHtml [String]
foodForm = listForm food