我正在尝试学习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