Tôi cố gắng để viết một typeclass mà đơn giản hoá việc viết một backend CRUD sử dụng dai dẳng, aeson và scottydai dẳng: CRUD TypeClass
Đây là ý tưởng của tôi:
runDB x = liftIO $ do info <- mysqlInfo
runResourceT $ SQL.withMySQLConn info $ SQL.runSqlConn x
class (J.FromJSON a, J.ToJSON a, SQL.PersistEntity a) => CRUD a where
getBasePath :: a -> String
getCrudName :: a -> String
getFromBody :: a -> ActionM a
getFromBody _ = do body <- jsonData
return body
mkInsertRoute :: a -> ScottyM()
mkInsertRoute el =
do post (fromString ((getBasePath el) ++ "/" ++ (getCrudName el))) $ do
body <- getFromBody el
runDB $ SQL.insert body
json $ J.Bool True
mkUpdateRoute :: a -> ScottyM()
mkDeleteRoute :: a -> ScottyM()
mkGetRoute :: a -> ScottyM()
mkGetAllRoute :: a -> ScottyM()
này doesn Không biên dịch, tôi nhận được lỗi này:
Could not deduce (SQL.PersistEntityBackend a
~ Database.Persist.GenericSql.Raw.SqlBackend)
from the context (CRUD a)
bound by the class declaration for `CRUD'
at WebIf/CRUD.hs:(18,1)-(36,36)
Expected type: SQL.PersistEntityBackend a
Actual type: SQL.PersistMonadBackend
(SQL.SqlPersist (Control.Monad.Trans.Resource.ResourceT IO))
In the second argument of `($)', namely `SQL.insert body'
In a stmt of a 'do' block: runDB $ SQL.insert body
In the second argument of `($)', namely
`do { body <- getFromBody el;
runDB $ SQL.insert body;
json $ J.Bool True }'
Có vẻ như tôi phải thêm một ràng buộc kiểu khác, chẳng hạn như PersistMonadBackend m ~ PersistEntityBackend a
, nhưng tôi không thấy như thế nào.
Cảm ơn! :-) Tôi đã kết thúc với một cái gì đó như thế quá, nhưng tôi thực sự muốn nó làm việc với tất cả các backend Persistent, không chỉ là những người dựa trên SQL. Tôi biết rằng runDB hiện tại thực thi điều này, vì vậy tôi nghĩ rằng tôi có thể cần trừu tượng hơn nữa. – agrafix
Ràng buộc đến từ việc thực thi mặc định của mkInsertRoute. Có lẽ bạn nên loại bỏ mặc định từ định nghĩa lớp, hoặc trừu tượng trên bit 'runDB $ SQL.insert'? –
Tôi nghĩ rằng nó đủ để trừu tượng hơn 'runDB'? – agrafix