public
Created

HTTP Fibonacci service in Haskell

  • Download Gist
http_wai_fib.hs
Haskell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
{-# LANGUAGE OverloadedStrings #-}
import Char
import Control.Monad (join)
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 (pack, unpack)
import Data.ByteString.Lazy.Char8 as LBS (pack, unpack)
import Data.Text as T (intercalate, pack, unpack)
 
headers :: ResponseHeaders
headers = [("Content-Type", "text/plain")]
 
app :: Application
app req
| rawPathInfo req == "/fib" = fibHandler req
| otherwise = notFoundHandler
 
fibHandler :: Request -> ResourceT IO Response
fibHandler req = do
case getFibIndex (queryString req) of
Nothing -> return $ responseLBS
badRequest400
headers
"bad request"
Just n -> return $ responseLBS
ok200
headers
(LBS.pack $ show $ fib n)
 
fib :: Int -> Int
fib n = fibs !! n
 
fibs :: [Int]
fibs = 1 : 2 : zipWith (+) fibs (tail fibs)
 
getFibIndex :: Query -> Maybe Int
getFibIndex query = Control.Monad.join (lookup "n" query) >>= extractInt
 
isInteger :: BS.ByteString -> Bool
isInteger bs = isInteger' $ B.unpack bs
where isInteger' xs = all isDigit xs
 
extractInt :: BS.ByteString -> Maybe Int
extractInt s = case isInteger s of
True -> Just $ read $ B.unpack s
False -> Nothing
 
notFoundHandler :: ResourceT IO Response
notFoundHandler = return $ responseLBS
status404
headers
"Not found"
 
main :: IO ()
main = do
BS.putStrLn $ "http://localhost:8080/"
run 8080 $ app

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.