dopatraman
dopatraman

Reputation: 13908

Implementing routing in haskell HTTP server

I'm trying to build a simple way to route requests based on the hostname. Here is the function:

handleAccept :: Handle -> String -> IO ()
handleAccept handle hostname = do
    putStrLn $ "Handling request from " ++ (getMessage hostname)
    request <- fmap (parseRequest . lines) (hGetContents handle)
    respond request handle
    return ()
    where getMessage x
        | x == "hello" = "hello route"
        | x == "LOL" = "what's so funny?"
        | otherwise = x

Called here:

main = withSocketsDo $ do
    sock <- listenOn (PortNumber 9000)
    putStrLn "Listening on port 9000"
    forever $ do
        (handle, hostname, port) <- accept sock
        handleAccept handle hostname
        hClose handle

When I try to compile I get this error:

parse error (possibly incorrect indentation or mismatched brackets)

at this line in handleAccept:

where getMessage x
        | x == "hello" = "hello route"

There seems to be an issue using guards with a where statement. So I tried this dummy function:

wherePlusGuards :: String -> Bool
wherePlusGuards x = getX x
    where getX x
        | x == "hello" = True
        | otherwise = False

This compiles fine. I'm left to believe that the issue is coming from using a where statement and guards inside a do expression. Why is this the case? Please help me.

Upvotes: 0

Views: 84

Answers (1)

ErikR
ErikR

Reputation: 52039

Make sure that the | is indented further than the g in getMessage - e.g.:

import System.IO

handleAccept :: Handle -> String -> IO ()
handleAccept handle hostname = do
    putStrLn $ "Handling request from " ++ (getMessage hostname)
    return ()
    where getMessage x
           | x == "hello" = "hello route"
           | x == "LOL" = "what's so funny?"
           | otherwise = x

Update

This does not parse correctly:

wherePlusGuards :: String -> Bool
wherePlusGuards x = getX x
    where getX x
        | x == "hello" = True
        | otherwise = False

It yields the error: parse error (possibly incorrect indentation or mismatched brackets)

Note: I'm not using any tabs.

From the Haskell2010 Report:

Note 1. A nested context must be further indented than the enclosing context (n > m). If not, L fails, and the compiler should indicate a layout error.

Reference: https://www.haskell.org/onlinereport/haskell2010/haskellch10.html

Section 10.3 (Layout), Note 1.

Upvotes: 3

Related Questions