我正在尝试学习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要求我定义一个函数,以将希望发送回HTML的HTML返回给发出HTTP请求的客户端。这意味着:

page = runSqlite "TestDB" $ do
    {pull data from the DB)


我无法通过runSqlite调用返回数据,并且据我所知,在page函数中没有变量,该变量在runSqlite do块中设置。我可以找到的所有示例都只需在runSqlite do块中写入IO,这不是此处需要做的。

最佳答案

runSqlite的类型是:

runSqlite :: (MonadBaseControl IO m, MonadIO m)  => Text -> SqlPersistT (NoLoggingT (ResourceT m)) a -> m a


selectList的类型是:

[Filter val] -> [SelectOpt val] -> m [Entity val]


因此,您实际上可以使用Monad的漂亮do表示法来提取它:

runSqlite "TestDB" $ do
  myData <- selectList ([] :: [Filter Person]) [] 0 0
  -- Now do stuff with myData


<-东西使列表脱离单子。我建议您仔细阅读chapter以了解如何使用持久性。请注意,本书中的各章假定您对Haskell有基本的了解。




问题是我想在runSqlite外部使用selectList作为
我需要将连接的字符串传递给Blaze HTML5标签构建器:
身体$做p(串联清单...)


对于这种情况,只需定义一个执行您预期任务的函数即可:

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

10-06 02:45