0

ユーザーが既存の値のリストから選択するか、新しい (テキスト) 値を作成できるフォームがあります。

それをコーディングする最もエレガントな方法は何ですか?

私の最善の(そしてIMOはそれほどエレガントではない)方法は、次のように定義することでした:

data MyInput = MyInput {createNew :: Bool, newVal :: Maybe Text, existingVal :: Maybe Text}

myForm :: [(Text,Text)] -> Html -> MForm MySite MySite (FormResult MyInput,Widget)
myForm exisingVals = renderTable $ MyInput
    <$> areq boolField "Create new" (Just False)
    <*> aopt textField "New val" Nothing
    <*> aopt (selectField existingVals) "Existing values" Nothing

フォームを受け取ったら、結果を次のように渡します。

getMyValue :: MyInput -> Either ErrorMsg Text
getMyValue i = if createNew i
                   then if newVal i == Nothing || existingVal i /= Nothing
                            then Left "Missing new value or illegal input"
                            else Right . fromJust . newVal $ i
                   else if existingVal i == Nothing || newVal i /= Nothing
                            then Left "Missing selection or illegal input"
                            else Right . fromJust . existingVal $ i

そして、ハンドラーにフォームを再送信するか、結果に従って続行するかを決定させます。

より良い/短い提案はありますか? 私の実際のフォームには、そのような選択/作成フィールドが 2 つあり、データ構造と処理がさらに面倒になります。ありがとう、

4

1 に答える 1

0

共通コードを除外し、パターンマッチングとガードを使用して、アクセサー関数を受け入れる高階関数で一般化することができます。

import Control.Arrow ((&&&))

getVal isNew newVal oldVal i | isNew i   = checkVal "new value" $ (newVal &&& oldVal) i
                             | otherwise = checkVal "selection" $ (oldVal &&& newVal) i
  where checkVal _ (Just val, Nothing) = Right val
        checkVal name _                = Left $ "Missing " ++ name ++ " or illegal input"

getMyVal = getVal createNew newVal existingVal
于 2012-02-08T17:27:24.053 に答える