我正在尝试学习 Haskell,特别是 Snap、Blaze HTML5 和 Persist。我想获取表中的每一行,从中选择一列,然后将这些值连接成一个字符串。
我之前曾广泛使用过 C# 的 LINQ,在 Entity Framework 下我可以这样做:
String.Join(", ", dbContext.People.Select(p => p.Name));
这将编译为 SELECT Name FROM People
,然后使用 C# 将这些行连接成一个字符串,中间用“,”进行连接。
为了尝试正确连接部分,我将其放在一起,这似乎有效:
intercalate ", " $ map show [1..10]
(计算 1-9,在项目之间用“,”连接)
但是,我无法让它与 Database.Persist.Sqlite 一起使用。我不确定我是否完全理解 Haskell 中的语法。要联系数据库并检索行,我必须调用:(据我所知)
runSqlite "TestDB" $ selectList ([] :: [Filter Person]) [] 0 0
问题是我不确定如何从 runSqlite
中获取列表。 runSqlite
不会返回我想要的类型,因此我无法使用 runSqlite 的返回值。我该怎么做?
感谢您的阅读。
<小时/>澄清一下:
Snap 要求我定义一个函数来返回我希望发送回发出 HTTP 请求的客户端的 HTML。这意味着:
page = runSqlite "TestDB" $ do
{pull data from the DB)
不行,因为我无法通过 runSqlite
调用返回数据,而且据我所知,page
中不能有变量在 runSqlite
do
block 中设置的函数。我能找到的所有示例都只是在 runSqlite
do
block 中写入 IO,这不是这里需要做的。
最佳答案
runSqlite的类型是:
runSqlite :: (MonadBaseControl IO m, MonadIO m) => Text -> SqlPersistT (NoLoggingT (ResourceT m)) a -> m a
以及 selectList 的类型是:
[Filter val] -> [SelectOpt val] -> m [Entity val]
所以,你实际上可以使用漂亮的 do
Monad 的表示法,提取它:
runSqlite "TestDB" $ do
myData <- selectList ([] :: [Filter Person]) [] 0 0
-- Now do stuff with myData
<-
thing 从 monad 中获取列表。我建议您仔细阅读此chapter了解如何使用持久性。请注意,本书中的章节假定您对 Haskell 有基本的理解。
The issue is that I want to use the selectList outside of runSqlite as I need to pass the concatenated string to a Blaze HTML5 tag builder: body $ do p (concatenated list...)
对于这种情况,只需定义一个函数来执行您的预期任务:
myLogic :: [SqlColumnData] -> String -- Note that SqlColumnData is hypothetical
myLogic xs = undefined
然后只需在您的 main
中适本地调用它们即可功能:
main = runSqlite "TestDB" $ do
myData <- selectList ([] :: [Filter Person]) [] 0 0
let string = myLogic myData
-- do any other remaining stuff
关于sqlite - 使用 Persist 将 Sqlite 表中所有记录中的一列提取到 Haskell 中的串联字符串中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24470269/