4

Yesod のブートストラップ 3 互換性を構築しようとしています。ただし、入力にクラスを追加できないため、「renderBootstrap3」関数を作成してこれを行うことはできません。そこで、フィールドのブートストラップ バージョンを で作成することにしましたForm.Fields。アイデアは、通常のフィールドを複製して、属性配列にクラス宣言を追加できるということです。関連するコードは次のとおりです。

import qualified Yesod.Form.Fields as F

injectClass :: (Text -> Text -> [(Text,Text)] -> Either Text a -> Bool -> WidgetT (HandlerSite m) IO ()
           Text -> Text -> [(Text,Text)] -> Either Text a -> Bool -> WidgetT (HandlerSite m) IO ()
injectClass f a b attrs d e = f a b attrs d e

textField :: (Monad m, RenderMessage (HandlerSite m) FormMessage) => Field m Text
textField = addInputClass F.textField

addInputClass :: (Monad m, RenderMessage (HandlerSite m) FormMessage) => Field m a -> Field m a
addInputClass f = f { fieldView = (injectClass $ fieldView f)}

したがって、私の意図は、テキスト フィールドの通常のバージョンを取得し、レコード構文を使用して fieldView メソッドのみを変更することです。このメソッドは、クラス属性の追加を除いて同一のメソッドに置き換える必要があります。これは、上記のコードではまだ実装されていません。おそらく次のようになります。

injectClass f a b attrs d e = f a b (("class", "form-control") : attrs) d e

とにかく、問題は元のコードがコンパイルされないことです。等式制約エラーが発生します。

Could not deduce (HandlerSite m0 ~ HandlerSite m)
from the context (Monad m,
                  RenderMessage (HandlerSite m) FormMessage)
  bound by the type signature for
             addInputClass :: (Monad m,
                               RenderMessage (HandlerSite m) FormMessage) =>
                              Field m a -> Field m a
  at Field/Bootstrap.hs:27:18-95
NB: `HandlerSite' is a type function, and may not be injective
The type variable `m0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Expected type: FieldViewFunc m a
  Actual type: Text
               -> Text
               -> [(Text, Text)]
               -> Either Text a
               -> Bool
               -> WidgetT (HandlerSite m0) IO ()
In the `fieldView' field of a record
In the expression: f {fieldView = (injectClass $ fieldView f)}
In an equation for `addInputClass':
    addInputClass f = f {fieldView = (injectClass $ fieldView f)}

FieldViewFunc m aとして定義されていることに注意してください

type FieldViewFunc m a
    = Text -- ^ ID
   -> Text -- ^ Name
   -> [(Text, Text)] -- ^ Attributes
   -> Either Text a -- ^ Either (invalid text) or (legitimate result)
   -> Bool -- ^ Required?
   -> WidgetT (HandlerSite m) IO ()

だから、私は遠く離れていません。問題は (私が思うに)injectClassモナドを変更しないことを認識していないことです。ただし、これはコンパイラにとって明らかなはずです。の型シグネチャinjectClassはこれについて明確です。GHCを満たすために何をする必要があるかを探しています。助けてくれてありがとう。もっと明確にできるかどうか教えてください。

4

2 に答える 2

0

もっと簡単な解決策があります。再定義areqaoptて、必要なクラスを自動的に追加できます。

areqBs3 :: (RenderMessage site FormMessage, HandlerSite m ~ site, MonadHandler m)
     => Field m a
     -> FieldSettings site
     -> Maybe a
     -> AForm m a
areqBs3 a b = areq a (b {fsAttrs = [("class", "form-control")]})
于 2013-10-11T13:48:55.130 に答える