私はここで、永続を使用してCRUDバックエンドを書く簡素化型クラスを書くためにアイソーンとスコッティ永続:CRUD型クラス
をしようとしていますが、私の考えです:
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()
このdoesnのコンパイルすると、私はこのエラーになります:
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 }'
PersistMonadBackend m ~ PersistEntityBackend a
のような別の型制約を追加する必要があるようですが、どうしたらいいか分かりません。
ありがとう! :-)私もそのようなもので終わりましたが、SQLベースのものだけでなく、すべての永続的なバックエンドで動作することが本当に好きです。私は現在のrunDBがこれを実施していることを知っているので、おそらくさらに抽象化が必要になると思います。 – agrafix
制約は、mkInsertRouteのデフォルトの実装から来ています。クラス定義からデフォルトを削除するか、 'runDB $ SQL.insert'ビットで抽象クラスを削除する必要がありますか? –
'runDB'で抽象化するだけで十分だと思いますか? – agrafix