Không có cách nào tiêu chuẩn để làm như vậy, nhưng digestive-functors
rất composable sử dụng giao diện Applicative
, vì vậy bạn có thể dễ dàng tạo ra những gì bạn muốn.
Bạn có thể xác định checkBox
trả về Maybe String
, tức là tên của phần tử nếu nó được chọn.
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
Bạn có thể sau đó lặp trên một danh sách các chuỗi để tạo ra một hộp kiểm như thế này cho mỗi phần tử trong danh sách:
listForm' :: (Functor m, Monad m)
=> [String]
-> HappstackForm m Html BlazeFormHtml [Maybe String]
listForm' = foldr (\x xs -> fmap (:) x <*> xs) (pure []) . map checkBox
Các catMaybes :: [Maybe a] -> [a]
giúp bạn giảm kết quả hơn nữa:
listForm :: (Functor m, Monad m)
=> [String]
-> HappstackForm m Html BlazeFormHtml [String]
listForm = fmap catMaybes . listForm'
Và cuối cùng, chúng tôi có thể khởi tạo biểu mẫu thực tế:
food :: [String]
food = ["Milk", "Cereals", "Ground meat"]
foodForm :: (Functor m, Monad m)
=> HappstackForm m Html BlazeFormHtml [String]
foodForm = listForm food
Thats khéo léo. Cảm ơn bạn – Masse
'listForm'' có thể được viết đơn giản hơn bằng cách sử dụng' Data.Traversable' như 'listForm '= traverse'. – hammar