1

URL ルート経由で情報を取得し、この情報をデータベースに渡す Web サイトを作成しようとしていHDBC SQLITE3ます。Scotty を使用してパラメーターを介して情報を取得する方法と、HDBC を使用してデータベースを作成する方法を理解しました。しかし、パラメーター情報をデータベースに渡すのに問題があります。次のエラーが表示されます: (このような初心者の問題で申し訳ありません。Haskell を使用してから約 3 週間しか経っていません)

Controllers/Home.hs:51:48:
No instance for (Convertible a0 SqlValue)
  arising from a use of `toSql'
Possible fix:
  add an instance declaration for (Convertible a0 SqlValue)
In the expression: toSql
In the expression: toSql $ userId
In the third argument of `run', namely
  `[toSql $ userId, toSql $ name]'

Controllers/Home.hs:51:64:
No instance for (Convertible a1 SqlValue)
  arising from a use of `toSql'
Possible fix:
  add an instance declaration for (Convertible a1 SqlValue)
In the expression: toSql
In the expression: toSql $ name
In the third argument of `run', namely
  `[toSql $ userId, toSql $ name]'

実行しようとしているコードは次のとおりです。

import Control.Monad
import Web.Scotty (ScottyM, ActionM, get, html, param)
import Data.Monoid (mconcat)
import Database.HDBC
import Database.HDBC.Sqlite3
import Control.Monad.Trans ( MonadIO(liftIO) )
import Data.Convertible
createUser ::  ScottyM()
createUser = get "/create/user/:userId/:name" $ do
  name <- param "name"
  userId <- param "userId"
  liftIO $ createUserDB name userId
  html $ mconcat ["<p>/create/user/" , userId , "/" , name ,"</p>"]
createUserDB :: a1 -> a0 -> IO()
createUserDB name userId = do
  conn <- connectSqlite3 databaseFilePath
  run conn "INSERT INTO users VALUES (? , ?)" [toSql $ userId, toSql $ name]
  commit conn
  disconnect conn
databaseFilePath = "data/mydb.db"

誰かがこれを修正する方法と、その修正が機能する理由を提供できれば、それは本当に役に立ちます!

4

1 に答える 1

1

createUserDBコードでは引数がエラーメッセージの制約を満たす必要があるため(つまり、引数が に変換可能である)、コンパイラが不平を言っていると思いますが、指定しSqlvalueた署名はその保証を提供しません(a0そしてa1任意の型にすることができます)。

最も簡単なオプションは、型シグネチャを削除してcreateUserDB、コンパイラに推論させることです。または、値に制限することもできTextます (nameuserIdはタイプTextでありDatabase.HDBC.SqlValue、 のインスタンスを定義するためConvertible Text SqlValue):

createUserDB :: Text -> Text -> IO ()

一般に、関数シグネチャでコンテキストを使用して型を制限することもできます。

createUserDB :: (Convertible a0 SqlValue, Convertible a1 SqlValue) => a1 -> a0 -> IO ()

しかし、型が明らかに SQL 文字列であり、おそらく varchar にマップされている場合、これはおそらく良い考えではありません。

于 2014-10-10T23:47:08.110 に答える