Haskell Happstack处理
我正在happstack中解析表单,但我不知道有什么更简洁的方法可以在服务器上收集表单变量。 有人知道这里是否有减少所需代码量的技巧吗Haskell Happstack处理,haskell,webforms,happstack,Haskell,Webforms,Happstack,我正在happstack中解析表单,但我不知道有什么更简洁的方法可以在服务器上收集表单变量。 有人知道这里是否有减少所需代码量的技巧吗 formHandler = do method POST delA1 <- look "address-01-delivery" delA2 <- look "address-02-delivery" delSuburb <- look "suburb-delivery" d
formHandler = do
method POST
delA1 <- look "address-01-delivery"
delA2 <- look "address-02-delivery"
delSuburb <- look "suburb-delivery"
delPostcode <- look "postcode-delivery"
delState <- look "state-delivery"
delCountry <- look "country-delivery"
bilA1 <- look "address-01-billing"
bilA2 <- look "address-02-billing"
bilSuburb <- look "suburb-billing"
bilPostcode <- look "postcode-billing"
bilState <- look "state-billing"
bilCountry <- look "country-billing"
formHandler=do
路标
delA1序言:这显然不会减少您在上面发布的代码量,但从长远来看,它可能会使事情更易于维护,因为它提供了一种一致的方法来执行验证,并允许您处理强类型对象,而不是大量的文本值
如果您要进行任意数量的表单处理,我建议您使用表单库。我个人使用过,并且发现与之共事很愉快。此外,它还附带了Happstack后端,这使得Happstack集成非常简单
这可能超出了您的投资范围,但下面是一个示例,说明了使用消化函子时表单代码的外观。我没有尝试编译任何这些,所以它可能会也可能不会工作,但希望它提供了总体思路
{-# LANGUAGE OverloadedStrings #-}
module Forms where
import Control.Applicative ((<$>), (<*>))
import Data.Text (Text)
import qualified Data.Text as T
import Happstack.Server
import Text.Digestive
data AddressState
= Alabama
| Alaska
| Arkansas
-- ...
deriving (Enum, Eq, Read)
data Country
= Canada
| Mexico
| UnitedStates
-- ...
deriving (Enum, Eq, Read)
data Address = Address
{ street1 :: Text
, street2 :: Maybe Text
, suburb :: Maybe Text
, postcode :: Int
, state :: AddressState
, country :: Country
}
data ShippingForm = ShippingForm
{ deliveryAddress :: Address
, billingAddress :: Address
}
addressForm :: (Monad m) => Form Text m Address
addressForm = Address
<$> "street1" .: nonEmptyText (text Nothing)
<*> "street2" .: optionalText Nothing
<*> "suburb" .: optionalText Nothing
<*> "postcode" .: stringRead "Please enter a valid postcode" Nothing
<*> "state" .: choice mkChoices Nothing
<*> "country" .: choice mkChoices Nothing
where
nonEmptyText = check "Cannot be empty" (not . T.null)
mkChoices = [(x, T.pack (show x)) | x <- [minBound .. maxBound]]
shippingForm :: (Monad m) => Form Text m ShippingForm
shippingForm = ShippingForm
<$> "delivery" .: addressForm
<*> "billing" .: addressForm
formHandler :: ServerPart Response
formHandler = do
method POST
decodeBody $ defaultBodyPolicy "/tmp" 4096 4096 4096
res <- runForm "shipping" shippingForm
case res of
(view, Nothing) -> do
-- setup your view
ok $ toResponse () -- <-- replace this with your view code
(_, Just formData) -> do
-- here, formData is a fully valid `ShippingForm`
let delStreet1 = (street1 . deliveryAddress) formData
-- do whatever you need to with this data (ie: persist it to a database, etc)
ok $ toResponse ()
{-#语言重载字符串}
模块形式在哪里
导入控件。应用程序((),())
导入数据。文本(Text)
导入符合条件的数据。文本为T
导入hapstack.Server
导入文本。消化
数据地址状态
=阿拉巴马州
|阿拉斯加
|阿肯色州
-- ...
派生(枚举、等式、读取)
数据国
=加拿大
|墨西哥
|美国
-- ...
派生(枚举、等式、读取)
数据地址=地址
{street1::Text
,street2::也许是文字
可能是文本
,邮政编码::Int
,state::AddressState
国家
}
数据ShippingForm=ShippingForm
{deliveryAddress::Address
,billingAddress::Address
}
addressForm::(单子m)=>格式文本m地址
addressForm=地址
“street1.”:非空文本(无文本)
“street2”:可选文本无
“郊区”:可选文本无
“邮政编码”。:stringRead“请输入有效的邮政编码”Nothing
“状态”。:选择无选择
“国家”:选择什么都没有
哪里
nonEmptyText=检查“不能为空”(not.T.null)
mkChoices=[(x,T.pack(show x))| x表单文本m发货表单
shippingForm=shippingForm
“交付”:地址表单
“账单”:地址表单
formHandler::ServerPart响应
formHandler=do
路标
decodeBody$defaultBodyPolicy“/tmp”4096 4096
雷斯多
--设置视图
ok$toResponse()--do
--在这里,formData是一个完全有效的“ShippingForm”`
让delStreet1=(street1.deliveryAddress)formData
--对这些数据执行任何需要的操作(例如:将其持久化到数据库等)
ok$toResponse()
有关消化函子的一些好的阅读资料,您可以查看以下链接:
[a,b,c]