Yesod - 提取会话数据(非String),存储并使用它

时间:2013-10-17 20:03:50

标签: haskell yesod

你好。

以下是我正在尝试的代码:

getGameR :: Handler Html
getGameR = do
    sess <- getSession
    defaultLayout $ do
        setTitle "Game"
        $(widgetFile "hamletFile")
    where
        person = read $ fromJust $ Map.lookup "person" sess :: Person

data Person = Person
    {
        name :: Text
    }
    deriving (Show, Read)


错误如下:

Handler/MyHandler.hs:87:56: Not in scope: `sess'


我正在尝试做的是从Yesod Session中提取数据(Person类型的数据)并将其存储在'person'中,以便能够在hamlet文件中使用它。

有没有办法解决这个错误?

如果不可能,你能建议另一种方法吗?

提前致谢。

2 个答案:

答案 0 :(得分:4)

sessdo块的本地,因此它不在person定义的范围内。就错误而言,在let块中使用do就足够了:

getGameR :: Handler Html
getGameR = do
    sess <- getSession
    let person = read $ fromJust $ Map.lookup "person" sess :: Person
    defaultLayout $ do
        setTitle "Game"
        $(widgetFile "hamletFile")

答案 1 :(得分:1)

如果您只想查找单个值,请考虑使用lookupSession。此外,如果密钥不在会话中,fromJust会抛出异常,您可以使用fromMaybe

getGameR :: Handler Html
getGameR = do
    mbPersonName <- lookupSession "person"
    let defaultPerson = Person "anonymous"
    let person = fromMaybe defaultPerson (readMaybe .unpack =<< mbPersonName) :: Person
    defaultLayout $ do
        setTitle "Game"
        $(widgetFile "hamletFile")

以下是我处理会话的助手:

import Text.Read (readMaybe)
import Data.Maybe (fromMaybe)

readSession :: Read a => Text -> Handler (Maybe a)
readSession name = do
    textValue <- lookupSession name
    return (readMaybe . unpack =<< textValue)

readSessionDef :: Read a => a -> Text -> Handler a
readSessionDef def name =  do
    mbValue <- readSession name
    return $ fromMaybe def mbValue

readSession读取任何可以读取的内容并返回Maybe。如果会话中不存在此键,则readSessionDef将返回默认值:

getGameR :: Handler Html
getGameR = do
    person <- readSessionDef (Person "anonymous") "person"
    defaultLayout $ do
        setTitle "Game"
        $(widgetFile "hamletFile")