nie ma standardowego sposobu, aby to zrobić, ale jest wysoce digestive-functors
composable pomocą interfejsu Applicative
, dzięki czemu można łatwo tworzyć, co chcesz.
Można zdefiniować wartość checkBox
, która zwraca wartość Maybe String
, tj. Nazwę elementu, jeśli została zaznaczona.
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
Można następnie pętli nad listą ciągów stworzyć wyboru takiego dla każdego elementu w liście:
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]
pomaga zmniejszyć efekt dalej:
listForm :: (Functor m, Monad m)
=> [String]
-> HappstackForm m Html BlazeFormHtml [String]
listForm = fmap catMaybes . listForm'
I na koniec możemy utworzyć konkretny formularz:
food :: [String]
food = ["Milk", "Cereals", "Ground meat"]
foodForm :: (Functor m, Monad m)
=> HappstackForm m Html BlazeFormHtml [String]
foodForm = listForm food
To genialne. Dziękuję – Masse
'listForm'' można napisać po prostu używając' Data.Traversable' jako 'listForm '= traverse checkBox'. – hammar