如何限制函数的调用者在Haskell中传递连接字符串?

时间:2017-07-18 22:19:56

标签: sql haskell

我正在检查由Bryan O'Sullivan编写的名为mysql-simple的mysql的haskell客户端库。该库不允许用户使用连接字符串作为查询。

以下工作正常:

myQuery :: Query
myQuery = "SELECT id, name FROM users LIMIT 1"

然而,这失败了:

myQuery :: Query
myQuery = "SELECT id, name FROM users LIMIT 1" ++ ""

这是运行以下示例时出现的错误:

do
  rows <- (query_ connection myQuery) :: IO [( Int , String)]
...


• Couldn't match expected type ‘Query’ with actual type ‘[Char]’
• In the expression: "SELECT id, name FROM users LIMIT 1" ++ ""
  In an equation for ‘myQuery’:
      myQuery = "SELECT id, name FROM users LIMIT 1" ++ ""

我的问题是是什么使这种限制成为可能?

我可以从source code看出这是故意的,但我无法理解它背后的基本概念。是因为Query类型不是String所属的类型类的实例吗?此外,即使我连接字符串,类型检查器不应该推断结果字符串可以用作Query吗?

提前致谢。

1 个答案:

答案 0 :(得分:5)

实际上,它确实允许连接字符串作为查询。您只需要使用一个对查询进行操作的连接运算符:

myQuery :: Query
myQuery = "SELECT id, name FROM users LIMIT 1" <> ""

(++)运算符特定于列表,而(<>)适用于任何Monoid(而QueryMonoid的实例,但不是列表类型)。

要回答您的其他问题:String永远不能用作Query。我怀疑它可以来自OverloadedStrings扩展,它允许你编写字符串文字并通过隐式应用{{1}将它们解释为String以外的类型}} 给他们。所以,例如。

fromString

实际上是foo = "foo" 的缩写。所以想象一下没有扩展的工作,你可以看到这两者之间的区别:

foo = fromString "foo"

前者对应你所写的内容;后者对应于你的意思。