Список флажков с пищеварительными функторами

Как использовать пищеварительные функторы для создания формы, которая имеет программно сгенерированный список флажков, который возвращает список. Например:

[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
Другие вопросы по тегам