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
我一直在关注 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