Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cassandra/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 使用snaplet会话时出现类型错误_Haskell_Haskell Snap Framework - Fatal编程技术网

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 ()