我正在尝试使用WAI编写一个简单的Fibonacci Web服务器,但我无法弄清楚这些类型。这段代码是我想要做的事情的本质,但它已经破碎了。 getQueryArg
函数返回Maybe ByteString
,我想在我的fibHandler
函数中使用它。
Maybe
中的fibHandler
?fmap
,但我似乎无法做到正确。
{-# LANGUAGE OverloadedStrings #-}
import Network.Wai
import Network.HTTP.Types
import Network.Wai.Handler.Warp (run)
import Data.ByteString.Lazy.Char8 () -- Just for an orphan instance
import Control.Monad.IO.Class (liftIO)
import Data.Conduit
import Data.String.Utils
import Data.ByteString as BS (ByteString, putStrLn)
import Data.ByteString.Char8 as B (unpack)
import Data.Text as T (intercalate, pack, unpack)
app :: Application
app req
| rawPathInfo req == "/fib" = fibHandler req
| otherwise = notFoundHandler
fibHandler :: Request -> ResourceT IO Response
fibHandler req = do
let nStr = getQueryArg (queryString req) "n"
fmap (liftIO . BS.putStrLn) n
let n = read nStr
return $ responseLBS
status200
[("Content-Type", "text/plain")]
(show $ fib n)
fib :: Int -> Int
fib n = foldl (*) 1 [1..n]
getQueryArg :: Query -> BS.ByteString -> Maybe BS.ByteString
getQueryArg [] key = Nothing
getQueryArg ((k,v):qs) key
| k == key = Just v
| otherwise = getQueryArg qs key
notFoundHandler :: ResourceT IO Response
notFoundHandler = return $ responseLBS
status404
[("Content-Type", "text/plain")]
"Not found"
main :: IO ()
main = do
BS.putStrLn $ "http://localhost:8080/"
run 8080 $ app
[更新:此代码的工作副本位于:https://gist.github.com/3145317]
答案 0 :(得分:6)
使用Maybe
值最简单的方法是使用case
。
case getQueryArg foo bar of
Nothing -> {- something went wrong, write some code to report an error -}
Just x -> {- everything went okay, and x is the result of the successful computation -}
一旦你完成了几十次,你就可以毕业于速记版本:
maybe ({- went wrong -}) (\x -> {- successful x -}) (getQueryArg foo bar)
fromMaybe {- default value -} (getQueryArg foo bar)
traverse_ B.putStrLn (getQueryArg foo bar) -- this trick is a personal favorite