2013-07-27 17 views
1

這是一個後續行動,我的問題在這裏:Extracting database field values inside a Handler傳遞標籤值的形式,文本/字符串

我想從數據庫中提取一些信息,並把它作爲一個形式的標籤值。但是,我收到一個類型錯誤。

一個簡單的演示之下(從耶索德書shell代碼):

{-# LANGUAGE MultiParamTypeClasses #-} 
{-# LANGUAGE OverloadedStrings  #-} 
{-# LANGUAGE QuasiQuotes   #-} 
{-# LANGUAGE TemplateHaskell  #-} 
{-# LANGUAGE TypeFamilies   #-} 
import   Control.Applicative ((<$>), (<*>)) 
import   Data.Text   (Text) 
import   Data.Time   (Day) 
import   Yesod 
import   Yesod.Form.Jquery 

data App = App 

mkYesod "App" [parseRoutes| 
/HomeR GET 
|] 

instance Yesod App 

instance RenderMessage App FormMessage where 
    renderMessage _ _ = defaultFormMessage 

instance YesodJquery App 

data Person = Person 
    { personName   :: Text 
    } 
    deriving Show 

personForm :: Text -> Html -> MForm Handler (FormResult Person, Widget) 
personForm n1 = renderDivs $ Person 
    <$> areq textField n1 Nothing -- Changing n1 to "Name" works just fine. 


getHomeR :: Handler Html 
getHomeR = do 
    (widget, enctype) <- generateFormPost $ personForm "test" 
    defaultLayout 
     [whamlet| 
      <p> 
       The widget generated contains only the contents 
       of the form, not the form tag itself. So... 
     |] 


main :: IO() 
main = warp 3000 App 

當我運行程序與runhaskell,我得到以下錯誤:

Couldn't match expected type `FieldSettings site0' 
      with actual type `Text' 
In the second argument of `areq', namely `n1' 
In the second argument of `(<$>)', namely 
    `areq textField n1 Nothing' 
In the second argument of `($)', namely 
    `Person <$> areq textField n1 Nothing' 

我也試過(FieldSettings n1 Nothing Nothing Nothing [])但沒有運氣。有關如何將標籤值傳遞給areq的想法?

回答

1

讓我們來看看areq

areq :: (RenderMessage master msg, RenderMessage master FormMessage) => Field sub master a -> FieldSettings msg -> Maybe a -> AForm sub master a 

類型,這樣areq功能估計不會有Text值作爲其第二個參數,它需要一個FieldSettings msg。那麼當你在源代碼中寫入「Name」時,它的工作原理是什麼?

the documentation for yesod-forms中查找關於FieldSettings的文檔,我們看到它是一個具有IsString實例的數據類型。在the source code 望着具體實例中,我們看到:

instance (a ~ Text) => IsString (FieldSettings a) where 
fromString s = FieldSettings (fromString s) Nothing Nothing Nothing [] 

所以每次你寫一個字符串在你的源代碼(如果啓用了OverloadedStrings擴展名),編譯器將插入fromString實例的內容。

但是,您不想輸入字符串,而是想要從Text值創建FieldSettings。進一步看,我們看到FieldSettings的第一部分是SomeMessage,檢查documentation yet againsource我們看到SomeMessage可以通過使用SomeMessage構造函數創建。

personForm :: Text -> Html -> MForm Handler (FormResult Person, Widget) 
personForm n1 = renderDivs $ Person 
    <$> areq textField (FieldSettings (SomeMessage n1) Nothing Nothing Nothing []) Nothing 
+0

非常感謝@danvari對引用字符串的工作原因作了明確的解釋。我確實嘗試了FieldSettings方法,但是最初沒有足夠的參數,我添加了一個空列表。之後,我回來了一個類似的錯誤:無法匹配預期的類型'SomeMessage site0' 與實際類型'文本' – Ecognium

+0

你是對的,我看了一個老版本的Yesod文檔。更新了答案。 – dnaq

+0

謝謝!這樣可行! – Ecognium

相關問題