Yesod 用の Paginator パッケージがあることは知っていますが、よりシンプルな UI を好むので、アプリ用のシンプルなページネーション ロジックを作成していました。ただし、パラメーター値を整数に変換する方法がわかりませんでした。
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」を 1 ( Data.Text.singleton '1'
) に変更しても、まったく同じエラー メッセージが表示されます。
ありがとう!