Haskell 使用snaplet会话时出现类型错误
应用程序类型Haskell 使用snaplet会话时出现类型错误,haskell,haskell-snap-framework,Haskell,Haskell Snap Framework,应用程序类型 data App = App { _heist :: Snaplet (Heist App) , _session :: Snaplet SessionManager } 初始值设定项 ... addRoutes [ ("/ss", companyHandler) , ("", heistServe) ] ... 处理者 companyHandler :: Handler b v () comp
data App = App
{ _heist :: Snaplet (Heist App)
, _session :: Snaplet SessionManager
}
初始值设定项
...
addRoutes [ ("/ss", companyHandler)
, ("", heistServe)
]
...
处理者
companyHandler :: Handler b v ()
companyHandler = method GET getter <|> method POST setter
where
getter = do
value <- getFromSession "name"
writeText $ fromMaybe "nothing" value
setter = do
mname <- getParam "name"
setInSession "name" (convert mname)
getter
convert = T.pack . B.unpack . (fromMaybe "nothing")
您必须先将
SessionManager
绑定到处理程序的上下文,然后才能使用对其进行操作的函数。这是通过以下方式完成的:
withTop session $ setInSession "name" (convert mname)
-- Where session is the generated lens for your snaplet
如果您还想在以后提交会话(因为您更改了会话,而不仅仅是读取变量),则需要:
withSession . withTop session $ ...
如果将以下代码添加到主应用程序的snaplet初始化代码中,则根本不必担心提交会话,因为这是为您自动完成的:
wrapHandlers withSession
解决此问题的一种方法是使用以下行:
companyHandler = with session $ method GET getter <|> method POST setter
大多数情况下,您不会编写可跨多个应用程序重用的通用代码,因此这里的通用性损失不会对您造成伤害。拥有更具体的类型签名通常会使错误消息更容易破译,这对代码编译有很大帮助。即使在我编写的代码应该是所有应用程序/Snaplet的通用代码时,有时我仍然发现从更具体的类型开始,然后在工作后进行通用化是很有帮助的
dflemstr关于Session的说法是正确的。我通常更喜欢一次性使用Session,而不是在调用setInSession时使用它,但是您应该做适合您的应用程序的任何事情。它不起作用
withSession会话$setInSession“name”(convert mname)::Handler b SessionManager()
,对于setInSession::Text->Text->Handler b SessionManager()
,很抱歉,我没有测试代码,这是我应该做的。会话API似乎是以一种奇怪的方式构造的;您需要将与top一起使用,而不是将与session一起使用。如果使用Session执行。使用Top session$…
,它将为您完成会话后提交会话。它可以编译,但会话不会在请求之间共享。完整的代码是,问题不在于会话管理系统,而在于测试方法。看,谢谢,现在可以用了。最后一个问题是提交会话
做什么?我发现使用和不使用它没有区别。
companyHandler = with session $ method GET getter <|> method POST setter
companyHandler :: Handler App App ()