Json postgres simple-没有因使用“query”而产生的(ToRow Int)实例

Json postgres simple-没有因使用“query”而产生的(ToRow Int)实例,json,postgresql,haskell,haskell-spock,postgresql-simple,Json,Postgresql,Haskell,Haskell Spock,Postgresql Simple,我是哈斯凯尔的新手,在这方面真的很艰难。但它扩展了我的思维,所以我们开始吧。 我正在尝试运行一个非常简单的Web服务器,它查询Postgres数据库,并将结果作为JSON返回 查询非常简单: 从MYTABLE中选择id,其中id=1 但是haskell的类型系统现在正在扼杀我,我的行为的最终类型不匹配。 我使用和作为组合 大多数教程要么简单到我想做的,要么很难。我介于两者之间,错过了很多Haskell的理解,我以前的很多问题我已经通过简单的复制和粘贴解决了,并且得到了一个简单的版本 但一旦我试图

我是哈斯凯尔的新手,在这方面真的很艰难。但它扩展了我的思维,所以我们开始吧。 我正在尝试运行一个非常简单的Web服务器,它查询Postgres数据库,并将结果作为JSON返回

查询非常简单: 从MYTABLE中选择id,其中id=1

但是haskell的类型系统现在正在扼杀我,我的行为的最终类型不匹配。 我使用和作为组合

大多数教程要么简单到我想做的,要么很难。我介于两者之间,错过了很多Haskell的理解,我以前的很多问题我已经通过简单的复制和粘贴解决了,并且得到了一个简单的版本

但一旦我试图传递一个路由变量,我就失败了。 这是我的工作版本。我的数据库表在这里称为Envelope,重要的调用是其中的get json:

我得到的错误是:

 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)
即使没有lambda函数,我也无法仅返回查询中的第一项

完整源代码可在上找到

我希望有人有时间来帮我。
感谢您的阅读。

错误的基本意思是不能将Int作为第三个参数传递给query。查询需要具有typeclass实例且Int不是一个实例的内容。考虑到您只想将一个值传递给查询,在您的情况下,您可能想要做的是使用。所以这条线变成:

query conn  "select id,data from envelope where id = ?" (Only (eid :: Int))

基于soupis的帮助,我还在Postgres-Simple文档中找到了相应的部分。为了补充说明,文档中提到了另一种语法,使用单例列表。因此,不用普通方括号,只需使用方括号,也可以:

查询连接选择id,来自信封的数据,其中id=?[eid::Int]

此外,特别是在我的示例中,只返回结果的第一行更有意义,结果证明,它与head函数是直接对应的。对于任何其他需要它的人,以下是您的做法:

斯波克和前奏曲都有头部功能。为了避免冲突,我决定隐藏Spocks函数,因为我没有使用它

在顶部添加到脚本:

导入Web.Spock隐藏头

然后将“获取”部分更改为:


完成。

什么,就这样?在经历了这么多令人头痛的思考之后?非常感谢,这很有效。这让我非常困惑,为什么有两个参数,你可以简单地做parA:Int,parB:Int,但是有了oneparam,你必须做唯一的表示法。但在你给我指出后,我在Postgres Simple Docs中找到了一些关于这方面的评论,所以我想我以后会理解它。在这种情况下,你可以将Int等类型视为一列,将tuple视为一行两列,将其视为一行一列。查询只处理行,所以您需要将列放在行中。这有点类似于在sql中的insert语句中使用值。您不能只传递1,您需要值1或选择1。现在更有意义了。谢谢
 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)
query conn  "select id,data from envelope where id = ?" (Only (eid :: Int))
get ( "json" <//> var  ) $ \eid -> do
      xs<-runQuery $ \conn -> 
        query conn  "select id,data from envelope where id = ?" [eid :: Int]
      json $ head (xs::[Envelope])