0

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.

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

4 Comments

why would that matter? What is the indent count that the parser looks for?
Answer updated - are you sure about wherePlusGuards parsing ok? it doesn't parse for me.
Reference from the Haskell Report added.
interesting... it compiles when i use tabs. thanks for clearing that up.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.