具有WAI的斐波纳契网络服务

时间:2012-07-18 23:38:29

标签: http haskell haskell-wai

我正在尝试使用WAI编写一个简单的Fibonacci Web服务器,但我无法弄清楚这些类型。这段代码是我想要做的事情的本质,但它已经破碎了。 getQueryArg函数返回Maybe ByteString,我想在我的fibHandler函数中使用它。

  1. 如何正确处理Maybe中的fibHandler
  2. 如何在Maybe上调用putStrLn?我正在尝试fmap,但我似乎无法做到正确。
  3. {-# 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]

1 个答案:

答案 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