首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Heist模板中使用postgresql-simple的结果

在Heist模板中使用postgresql-simple的结果
EN

Stack Overflow用户
提问于 2013-11-27 13:02:15
回答 1查看 323关注 0票数 2

我正在尝试将这个Heist tutorial和这个postgresql-simple tutorial结合起来。

我试着做了不同的变化。

代码语言:javascript
复制
splice :: C.Splice IO  
splice =  do  
  projects <- query_ "SELECT * FROM projects"  
  C.manyWithSplices C.runChildren projectSplice $ return (projects :: [Project])  
  where  
    projectSplice = do  
      "title" ## (C.pureSplice . C.textSplice $ title)  
      "description" ## (C.pureSplice . C.textSplice $ description)  

但我一直收到这个错误。

代码语言:javascript
复制
No instance for (HasPostgres (HeistT IO IO))
  arising from a use of 'query_'
Possible fix:
  add an instance declaration for (HasPostgres (HeistT IO IO))
In a stmt of a 'do' block:
  projects <- query_ "SELECT * FROM projects"
In the expression:
  do { projects <- query_ "SELECT * FROM projects";
       C.manyWithSplices C.runChildren projectSplice 
       $ return (projects :: [Project]) }

我不知道如何实现该实例声明,而且我仍然不能完全掌握monads。我甚至不确定我是否在正确的轨道上。

编辑:感谢@mightybyte的回答,我想出了这个。

代码语言:javascript
复制
projectSplice = do
  "title" ## (C.pureSplice . C.textSplice $ title)
  "description" ## (C.pureSplice . C.textSplice $ description)

splice :: C.Splice (Handler App App)
splice =  C.manyWithSplices C.runChildren projectSplice $ lift $ query_ "SELECT * FROM projects"

getHeistState heistConfig = liftIO $ either (error "Heist Init failed") id <$> (runEitherT $ initHeist heistConfig)

getBuilder heistState = maybe (error "Render template failed") fst $ C.renderTemplate heistState "database"

getAllProjectsHeist :: Handler App App ()
getAllProjectsHeist = do
  let heistConfig = HeistConfig defaultInterpretedSplices defaultLoadTimeSplices ("project" ## splice) noSplices [loadTemplates "templates"]
  heistState <- getHeistState heistConfig
  builder <- getBuilder heistState
  writeBS $ toByteString builder
EN

回答 1

Stack Overflow用户

发布于 2013-11-27 23:37:18

你可能想要更多像这样的东西:

代码语言:javascript
复制
splice = do
  C.manyWithSplices C.runChildren projectSplices $ 
    lift $ query_ "SELECT * FROM projects"
  where
    projectSplices = do
      "title" ## (C.pureSplice . C.textSplice $ title)
      "description" ## (C.pureSplice . C.textSplice $ description)

这里的关键是理解类型。让我们稍微注释一下上面的结构:

代码语言:javascript
复制
splice :: Monad n => Splice n
splice = do
  foo
  C.manyWithSplices C.runChildren projectSplices $ do
    bar
    lift baz

符号foo与splice具有相同的类型,即Splice n,相当于HeistT n IO Blah。对于手头的讨论,Blah的细节并不重要。如果您查找manyWithSplices的类型签名,您将看到它返回Splice n,因此到目前为止一切看起来都很好。您的runChildrenprojectSplices似乎是正确的,所以让我们关注manyWithSplices的第三个参数。再次参考API文档,我们看到第三个参数的类型为RuntimeSplice n [a],因此这是bar必须具有的类型。但是RuntimeSplice到底是什么东西。如果您在API文档中单击它,您将看到它有一个MonadTrans类型类的实例。如果单击它,您将看到MonadTrans只定义了一个函数lift,这就是我们在这里使用的函数。结合lift的类型签名和我们已经发现的内容,我们可以得出结论,baz具有n [a]类型。

n是你的运行时单子,HeistT n IO是你的加载时单子。如果你在像Janrain教程这样的Snap web应用程序的上下文中工作,那么在你的例子中,n将是Handler b b。您指定了类型签名Splice IO,它在您的问题的上下文中不起作用,因为IO不是正确的monad。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20234286

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档