私は haskell に不慣れで、正直苦労しています。しかし、それは私の考えを拡大するので、ここに行きます。Postgres DB にクエリを実行し、結果を JSON として返す必要がある、非常に単純な Web サーバーを実行しようとしています。
クエリは非常に単純です: "Select id,data from MYTABLE where id = 1"
しかし、haskell の型システムが今私を殺しており、私のアクションの最終的な型が一致しません。SpockとPostgreSQL-Simpleをコンボとして使用しています。
ほとんどのチュートリアルは、私がやりたいことに対して単純なものか、難しいものです。私はその中間にいて、多くのHaskellの理解を欠いています.以前の問題の多くは、単純なコピーと貼り付けですでに解決しており、単純なバージョンが機能しています.
しかし、ルート変数を渡そうとするとすぐに失敗します。これが私の作業バージョンです。私のデータベーステーブルはここでは「封筒」と呼ばれています.重要な呼び出しはそれが言う場所get "json"
です:
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE FlexibleInstances #-}
module Main where
import Web.Spock
import Web.Spock.Config
import Database.PostgreSQL.Simple
import Data.Pool
import Data.Aeson (ToJSON(toJSON), object, (.=),Value)
import Database.PostgreSQL.Simple.FromRow
type AppAction a = SpockActionCtx () Connection AppSession AppState a
data AppState = EmptyState
data AppSession = EmptySession
data Envelope = Envelope { envId :: Int, envData :: Value } deriving Show
instance FromRow Envelope where
fromRow = Envelope <$> field <*> field
instance ToJSON Envelope where
toJSON (Envelope envA envB) = object [ "id" .= envA, "data" .= envB ]
main :: IO ()
main =
do pool<-createPool (connect (ConnectInfo "localhost" 5432 "" "" "envelopes") ) close 1 10 10
spockCfg <- defaultSpockCfg EmptySession (PCPool pool) EmptyState
runSpock 8080 (spock spockCfg app)
app :: SpockM Connection AppSession AppState ()
app = do
get root $
text "Hello World!"
get "json" $ do
xs<-runQuery $ \conn ->
query_ conn "select id,data from envelope where id = 1"
json (xs::[Envelope])
次に、ラムダ関数を使用してエンベロープ ID を渡そうとします。そのためには、PostgreSQL-Simplequery_
をquery
次のように変更する必要もあります。
get ( "json" <//> var ) $ \eid -> do
xs<-runQuery $ \conn ->
query conn "select id,data from envelope where id = ?" (eid :: Int)
json (xs::[Envelope])
私が得るエラーは言う:
No instance for (ToRow Int) arising from a use of ‘query’
In the expression:
query conn "select id,data from envelope where id = ?" (eid :: Int)
In the second argument of ‘($)’, namely
‘\ conn
-> query
conn "select id,data from envelope where id = ?" (eid :: Int)’
In a stmt of a 'do' block:
xs <- runQuery
$ \ conn
-> query
conn "select id,data from envelope where id = ?" (eid :: Int)
ラムダ関数がなくても、クエリから最初のアイテムだけを返すという問題もあります。
完全なソースはbitbucketにあります
誰かが私をここで助けてくれることを願っています。すでにお読みいただきありがとうございます。