YesodDB,如何正确放置类型
YesodDB, how to put types correctly
我已经创建了一个函数来加载一些 Entities
但我在理解如何放置它的类型声明时遇到了一些麻烦,所以我采用了这个 Yesod book chapter
关于 Yesod monads,为了更好地理解它,我来到了这个片段:
-- type Distance = Int
worksByNhood :: AdrNhoodId -> Int64 -> Int64 -> YesodDB App [(Entity Work, Int, [Entity WImage])]
worksByNhood nId offset' limit' = do
works <- select $ from $ \(w `InnerJoin` d) -> do
on $ d ^. AdrDistanceNhood2 ==. w ^. WorkNhood
where_ (d ^. AdrDistanceNhood1 ==. val nId)
orderBy [asc (d ^. AdrDistanceDistance)]
offset offset'
limit limit'
return (w, d ^. AdrDistanceDistance)
works' <- forM works $ \(w@(Entity wId _), d) -> do
images <- select $ from $ \wi -> do
where_ (wi ^. WImageWork ==. val wId)
return wi
return (w, d, images);
return works'
我认为类型声明中的 Int
需要以某种方式进行转换,更具体地说,我收到此错误:
Select.hs:20:12:
Couldn't match type ‘Database.Esqueleto.Value Distance’ with ‘Int’
Expected type: (Entity Work, Distance, [Entity WImage])
Actual type: (Entity Work,
Database.Esqueleto.Value Distance,
[Entity WImage])
In the first argument of ‘return’, namely ‘(w, d, images)’
In a stmt of a 'do' block: return (w, d, images)
In the expression:
do { images <- select $ from $ \ wi -> do { ... };
return (w, d, images) }
我记得有一个chapter about joins in the great Yesod book,所以我重新阅读并找到了解决方案,也许我的代码可以帮助别人,所以就这样:
module Select where
import Import hiding((==.), on, Value)
import Database.Persist.Sql (toSqlKey) -- Useful when I want to explicitly use primary keys
import Database.Esqueleto
-- type Distance = Int
worksByNhood :: AdrNhoodId -> Int64 -> Int64 -> YesodDB App [(Entity Work, Value Distance, [Entity WImage])]
worksByNhood nId offset' limit' = do
works <- select $ from $ \(w `InnerJoin` d) -> do
on $ d ^. AdrDistanceNhood2 ==. w ^. WorkNhood
where_ (d ^. AdrDistanceNhood1 ==. val nId)
orderBy [asc (d ^. AdrDistanceDistance)]
offset offset'
limit limit'
return (w, d ^. AdrDistanceDistance)
forM works $ \(w@(Entity wId _), d) -> do
images <- select $ from $ \wi -> do
where_ (wi ^. WImageWork ==. val wId)
return wi
return (w, d, images)
类型声明处的Value Distance
就是答案
我已经创建了一个函数来加载一些 Entities
但我在理解如何放置它的类型声明时遇到了一些麻烦,所以我采用了这个 Yesod book chapter
关于 Yesod monads,为了更好地理解它,我来到了这个片段:
-- type Distance = Int
worksByNhood :: AdrNhoodId -> Int64 -> Int64 -> YesodDB App [(Entity Work, Int, [Entity WImage])]
worksByNhood nId offset' limit' = do
works <- select $ from $ \(w `InnerJoin` d) -> do
on $ d ^. AdrDistanceNhood2 ==. w ^. WorkNhood
where_ (d ^. AdrDistanceNhood1 ==. val nId)
orderBy [asc (d ^. AdrDistanceDistance)]
offset offset'
limit limit'
return (w, d ^. AdrDistanceDistance)
works' <- forM works $ \(w@(Entity wId _), d) -> do
images <- select $ from $ \wi -> do
where_ (wi ^. WImageWork ==. val wId)
return wi
return (w, d, images);
return works'
我认为类型声明中的 Int
需要以某种方式进行转换,更具体地说,我收到此错误:
Select.hs:20:12:
Couldn't match type ‘Database.Esqueleto.Value Distance’ with ‘Int’
Expected type: (Entity Work, Distance, [Entity WImage])
Actual type: (Entity Work,
Database.Esqueleto.Value Distance,
[Entity WImage])
In the first argument of ‘return’, namely ‘(w, d, images)’
In a stmt of a 'do' block: return (w, d, images)
In the expression:
do { images <- select $ from $ \ wi -> do { ... };
return (w, d, images) }
我记得有一个chapter about joins in the great Yesod book,所以我重新阅读并找到了解决方案,也许我的代码可以帮助别人,所以就这样:
module Select where
import Import hiding((==.), on, Value)
import Database.Persist.Sql (toSqlKey) -- Useful when I want to explicitly use primary keys
import Database.Esqueleto
-- type Distance = Int
worksByNhood :: AdrNhoodId -> Int64 -> Int64 -> YesodDB App [(Entity Work, Value Distance, [Entity WImage])]
worksByNhood nId offset' limit' = do
works <- select $ from $ \(w `InnerJoin` d) -> do
on $ d ^. AdrDistanceNhood2 ==. w ^. WorkNhood
where_ (d ^. AdrDistanceNhood1 ==. val nId)
orderBy [asc (d ^. AdrDistanceDistance)]
offset offset'
limit limit'
return (w, d ^. AdrDistanceDistance)
forM works $ \(w@(Entity wId _), d) -> do
images <- select $ from $ \wi -> do
where_ (wi ^. WImageWork ==. val wId)
return wi
return (w, d, images)
类型声明处的Value Distance
就是答案