1

Every time I tried to run this code, the compiler returns a 'not in scope' error for the variables redirectUrlGraphEmail, redirectUrlGraphPost, aboutContents, and staticDir:

routes :: [ (String, ServerPart Response)]
routes = [
("graph-fb", seeOther redirectUrlGraphEmail $ toResponse ""),
("post-fb", seeOther redirectUrlGraphPost $ toResponse ""),               
("about", aboutResponse aboutContents),
("static", serveDirectory DisableBrowsing [] staticDir)]

These variables are declared by:

staticDir <- getStaticDir
redirectUrlGraphEmail <- retrieveAuthURL testUrl
redirectUrlGraphPost <- retrieveAuthURL testPostUrl
aboutContents <- LazyIO.readFile $ markdownPath ++ "README.md"
privacyContents <- LazyIO.readFile $ markdownPath ++ "PRIVACY.md"

but I am not sure where should I add these lines into the module. Any help here?

jwodder
  • 54,758
  • 12
  • 108
  • 124
Mia.M
  • 97
  • 1
  • 1
  • 8

1 Answers1

4

I don't know happstack but it seems that your variables redirectUrlGraphEmail etc. are defined in your main (or in some monad at least), right? And then you want to define route as a separate function in your module.

The thing is, the variables you define (that you bind with <- to be precise) in your main are local to your main, so the rest of your program doesn't have access to them (which is why the compiler tells you they're not in scope when you try to use them in routes). If you want to make use of them, you need to define routes as a function taking them as parameters, so in your case:

routes redirectUrlGraphEmail redirectUrlGraphPost = [
 ("graph-fb", seeOther redirectUrlGraphEmail $ toResponse ""),
 ("post-fb", seeOther redirectUrlGraphPost $ toResponse ""),               
 ("about", aboutResponse aboutContents),
 ("static", serveDirectory DisableBrowsing [] staticDir)]

And then from your main call routes with the variables you've bind. Am I making sense?

Guerric Chupin
  • 461
  • 2
  • 13
  • Yes, that makes a lot of sense to me. Thanks for your explanation! Another question here is in the main module, the way I call `routes` is `(map (\ (a, b) -> dir a b) $ routes)` ,which maps the function `dir` to each tuple in `routes`. And `dir` takes in two elements in the tuple both as variables. How can I combine this with calling `routes` in main with variables that I've bind? – Mia.M Aug 25 '16 at 08:13
  • If I understand your question correctly, you can simply apply `routes` to its arguments, so you can just write `map (\(a,b) -> dir a b) $ routes redirectUrlGraphEmail redirectUrlGraphPost…`. Note that in your original formulation, you didn't need the `$`, writing `map (\(a,b) -> dir a b) routes` would have been fine ;) – Guerric Chupin Aug 26 '16 at 00:10
  • I see! Then do I need to add those variables in my routes function? like `routes :: [ (String, ServerPart Response)] routes staticDir redirectUrlGraphEmail redirectUrlGraphPost aboutContents privacyContents = [ ("graph-fb", seeOther redirectUrlGraphEmail $ toResponse ""), ("post-fb", seeOther redirectUrlGraphPost $ toResponse ""), ("about", aboutResponse aboutContents), ("static", serveDirectory DisableBrowsing [] staticDir)]` – Mia.M Aug 26 '16 at 10:06