提问人:mandark 提问时间:7/19/2017 最后编辑:mandark 更新时间:7/20/2017 访问量:60
如何限制函数的调用者在Haskell中传递串联字符串?
How to restrict the caller of the function from passing concatenated strings in 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" ++ ""
我的问题是,是什么让这种限制成为可能?
从源代码中可以看出这是故意的,但我无法理解其背后的基本概念。是因为类型不是类型类的实例吗?另外,即使我连接了字符串,类型检查器也不应该推断生成的字符串可以用作?Query
String
Query
提前致谢。
答:
5赞
Daniel Wagner
7/19/2017
#1
实际上,它确实允许将串联字符串作为查询。您只需要使用对查询进行操作的串联运算符:
myQuery :: Query
myQuery = "SELECT id, name FROM users LIMIT 1" <> ""
运算符特定于列表,而适用于 any(并且是 的实例,但不是列表类型)。(++)
(<>)
Monoid
Query
Monoid
并回答你的另一个问题:a 永远不能用作 .我怀疑它可能来自扩展的信念,它允许您编写字符串文字并将它们解释为类型,而不是通过隐式应用它们。所以,例如String
Query
OverloadedStrings
String
fromString
foo = "foo"
实际上是 的缩写。所以想象一下没有扩展的工作,你可以看到这两者之间的区别:foo = fromString "foo"
foo1 = fromString "bar" ++ fromString "baz"
foo2 = fromString ("bar" ++ "baz")
前者与你写的相对应;后者符合你的意思。
评论
0赞
Daniel Wagner
7/19/2017
(注:未经测试。我只是参考了文档,我没有安装软件包并实际检查它是否有效。
0赞
mandark
7/19/2017
看到你的回复后,我意识到我可以使用,因为来源也显示了它。如果已导入,也可以使用运算符。另外,您关于重载字符串的评论是正确的。我应该在问题中澄清这一点,但您的回答解释了我想知道的内容。多谢!mappend
Data.Monoid
0赞
Daniel Wagner
7/19/2017
@mandark 是的,并且是同义词,只要导入正确。mappend
(<>)
评论