分页:将参数值转换为整数时出错

时间:2013-07-18 07:57:45

标签: haskell yesod

我知道Yesod有一个Paginator包,但我更喜欢更简单的UI,所以我为我的应用创建了一个简单的分页逻辑。但是,我无法找到将参数值转换为Integer的方法。

import Data.Text (unpack, singleton)
import Data.Maybe 

one = singleton '1' -- convert char to Text, required by fromMaybe

getTestPanelR :: Handler Html
getTestPanelR = do
    ptext <- lookupGetParam "p" -- guessing returns Maybe Text
    p <- fromMaybe one ptext -- ??? does  not work
    -- pn <- ??? Once p is extracted successfully, how to convert to an integer?

    s <- runDB $ selectList [] [Asc PersonName, LimitTo 10 , OffsetBy $ (pn - 1) * 10]
    (widget, enctype) <- generateFormPost $ entryForm Nothing
    defaultLayout $ do
        $(widgetFile "person")

当我运行上面的代码时,我收到以下错误消息:

No instance for (MonadHandler Maybe)
  arising from a use of `lookupGetParam'
Possible fix: add an instance declaration for (MonadHandler Maybe)
In the second argument of `($)', namely `lookupGetParam "p"'
In a stmt of a 'do' block:
  p <- fromMaybe one $ lookupGetParam "p"
In the expression:
...

当我使用 #{show ptext}写出'ptext'时,它会显示Just "1"。得到GET参数后,如何将其转换为整数以便我可以进行分页? (需要为'next'添加1并为'prev'减去1)

FWIW,当我尝试使用GHCi时,它运行正常:

Prelude Data.Maybe Data.Text> let one = singleton '1' 
Prelude Data.Maybe Data.Text> let x = Just $ singleton '5'
Prelude Data.Maybe Data.Text> let y = fromMaybe one x
Prelude Data.Maybe Data.Text> y
"5"
Prelude Data.Maybe Data.Text> read $ Data.Text.unpack y ::Int -- This is probably unsafe because I cannot trust 'y' in my web app
5

更新

我累了@Ankur的建议pageNumber <- (lookupGetParam "p" >>= return . (read :: String -> Int) . fromMaybe "1"),我收到以下错误:

Couldn't match expected type `String' with actual type `Text'
Expected type: Maybe Text -> String
  Actual type: Maybe Text -> Text
In the return type of a call of `fromMaybe'
In the second argument of `(.)', namely `fromMaybe "1"'
Build failure, pausing...

如果将“1”更改为一个(Data.Text.singleton '1'),我仍会得到完全相同的错误消息。

谢谢!

1 个答案:

答案 0 :(得分:1)

lookupGetParam返回ParamValuetype ParamValue = String。所以基本上它是String而不是Text。

试试这个:

pageNumber <- (lookupGetParam "p" >>= return . (read :: String -> Int) . fromMaybe "1") 

<强>更新

实际上lookupGetParam的最新版本是基于Text的,因此添加OverloadedStrings语言扩展应该可以完成工作:

将此{-# LANGUAGE OverloadedStrings #-}放在代码文件的开头,然后使用:

pageNumber <- (lookupGetParam "p" >>= return . (read :: String -> Int) . unpack . fromMaybe "1")