Reputation: 2674
I've been following this tutorial for learning Yesod, and am trying to run this simple form:
{-# 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
When I runhaskell forms.hs
, I get this error:
forms.hs:27:10:
‘AForm’ is applied to too many type arguments
In the type signature for ‘aform’: aform :: AForm App App Info
After futzing with a number of variations of the type signature, I kept getting errors. The ghci :info AForm
reads
Prelude Yesod> :info AForm
type role AForm nominal nominal
newtype AForm (m :: * -> *) a
But a change to aform :: AForm (App -> App) Info
gives me this error:
forms.hs:27:17:
The first argument of ‘AForm’ should have kind ‘* -> *’,
but ‘App -> App’ has kind ‘*’
Any ideas on how to resolve this?
Upvotes: 0
Views: 83
Reputation: 31355
The type signature for areq
is:
areq :: (RenderMessage site FormMessage, HandlerSite m ~ site, MonadHandler m) => Field m a -> FieldSettings site -> Maybe a -> AForm m a
Note how it takes two parameters, and the first parameter is an instance of MonadHandler
. Therefore, your signature on aform
will need to have the same parameter. In your code, this may look like:
aform :: AForm (HandlerT App IO) Info
or the shortened form:
aform :: AForm Handler Info
Have a look at the car example in the Yesod book.
Upvotes: 1