List of checkboxes with digestive-functors

拥有回忆 提交于 2019-12-10 02:25:04

问题


How do I use digestive functors to create a form that has a programmatically generated list of checkboxes, which would return a list. For example:

[x] Milk
[ ] Cereals
[x] Ground meat

would return ["Milk", "Ground meat"].

I'm expecting the type would be something like:

form :: (Functor m, Monad m) => [String] -> HappstackForm m Html BlazeFormHtml [String]

回答1:


There is no standard way to do so, but digestive-functors is highly composable using the Applicative interface, so you can easily create what you want.

You can define a checkBox which returns a Maybe String, i.e. the name of the element if it was checked.

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

You can then loop over a list of strings to create a checkbox like this for each element in the list:

listForm' :: (Functor m, Monad m)
          => [String]
          -> HappstackForm m Html BlazeFormHtml [Maybe String]
listForm' = foldr (\x xs -> fmap (:) x <*> xs) (pure []) . map checkBox

The catMaybes :: [Maybe a] -> [a] helps you to reduce the result further:

listForm :: (Functor m, Monad m)
         => [String]
         -> HappstackForm m Html BlazeFormHtml [String]
listForm = fmap catMaybes . listForm'

And finally, we can instantiate the actual form:

food :: [String]
food = ["Milk", "Cereals", "Ground meat"]

foodForm :: (Functor m, Monad m)
         => HappstackForm m Html BlazeFormHtml [String]
foodForm = listForm food


来源:https://stackoverflow.com/questions/6436238/list-of-checkboxes-with-digestive-functors

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!