Yesod 中的 aform 类型

aform types in Yesod

我一直在关注 this tutorial 学习 Yesod,并且正在尝试 运行 这个简单的形式:

{-# LANGUAGE TypeFamilies               #-}
{-# LANGUAGE QuasiQuotes                #-}
{-# LANGUAGE MultiParamTypeClasses      #-}
{-# LANGUAGE TemplateHaskell            #-}
{-# LANGUAGE OverloadedStrings          #-}
{-# LANGUAGE ViewPatterns               #-} 
import Control.Applicative((<$>),(<*>))
import Yesod

data App = App

mkYesod "App" [parseRoutes|
/accum Accum GET
|]

instance Yesod App

instance RenderMessage App FormMessage where
   renderMessage _ _ = defaultFormMessage

data Info = Info 
   { deposit :: Double
   , rate    :: Double
   , years   :: Double
   }

aform :: AForm App App Info
aform = Info
   <$> areq doubleField "Deposit" Nothing
   <*> areq doubleField "Rate" Nothing
   <*> areq doubleField "Years" Nothing

accum x = deposit x * (1 + rate x * years x)

mform = renderTable aform

getAccum :: Handler RepHtml
getAccum = do
   ((result, widget), enc) <- runFormGet mform
   case result of
      FormSuccess info -> defaultLayout [whamlet|<p> #{show (accum info)} |]
      _                -> defaultLayout [whamlet| 
      <form method=get action=@{Accum} enctype=#{enc}>
         <table>
            ^{widget}
         <input type=submit>
         |]

main = warpDebug 2012 App

当我 runhaskell forms.hs 时,我得到这个错误:

forms.hs:27:10:
    ‘AForm’ is applied to too many type arguments
    In the type signature for ‘aform’: aform :: AForm App App Info

在尝试了多种类型签名变体之后,我不断收到错误。 ghci :info AForm 读取

Prelude Yesod> :info AForm
type role AForm nominal nominal
newtype AForm (m :: * -> *) a

但是对 aform :: AForm (App -> App) Info 的更改给我这个错误:

forms.hs:27:17:
    The first argument of ‘AForm’ should have kind ‘* -> *’,
      but ‘App -> App’ has kind ‘*’

关于如何解决这个问题有什么想法吗?

areq 的类型签名是:

areq :: (RenderMessage site FormMessage, HandlerSite m ~ site, MonadHandler m) => Field m a -> FieldSettings site -> Maybe a -> AForm m a

注意它是如何接受两个参数的,第一个参数是 MonadHandler 的一个实例。因此,您在 aform 上的签名将需要具有相同的参数。在您的代码中,这可能类似于:

aform :: AForm (HandlerT App IO) Info

或缩写形式:

aform :: AForm Handler Info

看看the car example in the Yesod book