消化函数复选框列表

Mas*_*sse 9 haskell digestive-functors

如何使用消化函数创建一个具有以编程方式生成的复选框列表的表单,该表单将返回一个列表.例如:

[x] Milk
[ ] Cereals
[x] Ground meat
Run Code Online (Sandbox Code Playgroud)

会回来的["Milk", "Ground meat"].

我期待类型会是这样的:

form :: (Functor m, Monad m) => [String] -> HappstackForm m Html BlazeFormHtml [String]
Run Code Online (Sandbox Code Playgroud)

jas*_*vdj 14

没有标准的方法可以这样做,但digestive-functors使用Applicative界面可以高度组合,因此您可以轻松创建所需的内容.

您可以定义一个checkBox返回a 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
Run Code Online (Sandbox Code Playgroud)

然后,您可以循环遍历字符串列表,为列表中的每个元素创建一个这样的复选框:

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

catMaybes :: [Maybe a] -> [a]可以帮助您进一步降低结果:

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

最后,我们可以实例化实际形式:

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

foodForm :: (Functor m, Monad m)
         => HappstackForm m Html BlazeFormHtml [String]
foodForm = listForm food
Run Code Online (Sandbox Code Playgroud)