我有以下持久模型:
User
ident Text
password Text Maybe
UniqueUser ident
deriving Typeable
Payment
timestamp UTCTime
from UserId
to UserId
amount Int
我正在尝试构建一个页面,显示数据库中所有付款的列表,每个付款链接指向付款/收到付款的用户。目前我的代码是:
getPaymentsR :: Handler Html
getPaymentsR = do
let payments = map addFromTo $ runDB $ selectList [] [Desc PaymentTimestamp]
defaultLayout
[whamlet|
<h3> Payments
<ul>
$forall (key, value, from, to) <- payments
<li>
<a href=@{UserR $ paymentFrom value}> #{from} </a> paid #{paymentAmount value} to <a href=@{UserR $ paymentTo value}> #{to} </a> on #{printDay $ paymentTimestamp value}
$if null payments
<ul>
<li> No payments
|]
where
addFromTo :: Entity Payment -> (Key Payment, Payment, Text, Text)
addFromTo (Entity key val) = do
let from = runDB $ get404 $ paymentFrom val
let to = runDB $ get404 $ paymentTo val
(key, val, userIdent from, userIdent to)
但是我收到以下错误:
Handler/Payment.hs:9:36:
Couldn't match expected type `[Entity Payment]'
with actual type `HandlerT site0 IO [Entity Payment]'
In the second argument of `($)', namely
`runDB $ selectList [] [Desc PaymentTimestamp]'
In the expression:
map addFromTo $ runDB $ selectList [] [Desc PaymentTimestamp]
In an equation for `payments':
payments
= map addFromTo $ runDB $ selectList [] [Desc PaymentTimestamp]
Handler/Payment.hs:26:34:
Couldn't match expected type `User'
with actual type `HandlerT site0 IO User'
In the first argument of `userIdent', namely `from'
In the expression: userIdent from
In a stmt of a 'do' block: (key, val, userIdent from, userIdent to)
Handler/Payment.hs:26:50:
Couldn't match expected type `User'
with actual type `HandlerT site1 IO User'
In the first argument of `userIdent', namely `to'
In the expression: userIdent to
In a stmt of a 'do' block: (key, val, userIdent from, userIdent to)
有人知道我做错了什么,或者如何解决这些错误? 我认为它与Extracting database field values inside a Handler有很大关系。 但是我仍无法解决上述链接中的信息问题。
更新
使用Michael Snoyman的答案编辑我的代码后,我的新addFromTo函数仍然会出现类型错误:
addFromTo :: Entity Payment -> (Key Payment, Payment, Text, Text)
addFromTo (Entity key val) = do
from' <- runDB $ get404 $ paymentFrom val
to' <- runDB $ get404 $ paymentTo val
let from = userIdent from'
let to = userIdent to'
(key, val, from, to)
答案 0 :(得分:3)
这里的问题是你将monadic动作视为纯粹的价值。解决这个问题的更简单方法是使用do-notation和slurp运算符:
payments' <- runDB $ selectList [] [Desc PaymentTimestamp]
let payments = map addFromTo payments'
或者如果你想获得更好的(不一定推荐):
payments <- fmap (map addFromTo) $ runDB $ selectList [] [Desc PaymentTimestamp]