purescript-contrib/purescript-routing

Understanding on what `lit` and `src` behaviors

Opened this issue · 4 comments

@natefaubion, continuing my chat in slack, and trying to avoid slack archive.. i'll put my reply in here.

Here is the guide said:

```  -- | `lit x` will match exactly the path component `x`.
  -- | For example, `lit "x"` matches `/x`.
  lit :: String -> f Unit

  -- | `str` matches any path string component.
  -- | For example, `str` matches `/foo` as `"foo"`.
  str :: f String```

I just want to correct my logic in how purescript-routing act. So, my understanding is, the library trying to match the uri address with the pattern we describe in routing :: Match a function. How it works is it stripped the uri address (let say mysite.com/#/foo/bar/FooBar) until the # sign.

So, we will have #/foo/bar/FooBar, which in this case, if we use the above guide, lit "x" matches "/x" and "str" matches "/foo" as "foo", then the stripped address can be matched with this:

#/foo        /bar         /FooBar
  (lit "foo") (lit "bar") (lit "FooBar")

but instead, i have to do this:

#/foo                     /bar                    /FooBar
  (lit "" <* lit "foo") (lit "" <*lit "bar") (lit "" <* lit "FooBar")

and if we see the guide again, it looks like it is "//foo//bar//FooBar". I know that we use <* or *> that supposed to remove the lit "". But why can't we just use the former example one??? I mean why we can't just write it :
FooBarPage <$ (lit "foo" *> lit "bar" *> lit "FooBar" )

Instead of:

FooBarPage <$ (lit "" *> lit "foo" *> lit "" *> lit "bar" *> lit "" *> lit "FooBar" )

the same goes if we have FooBarPage String, by using the guide again, we supposed to write:

FooBarPage <$> (lit "foo" *> lit "bar" *> lit "" *> lit "FooBar" )

instead of
FooBarPage <$ (lit "" *> lit "foo" *> lit "" *> lit "bar" *> lit "FooBar" )

Right? I am sorry if my understanding is not what the guide supposed to mean. But from beginner pov (like me), reading the source's comment explanation is very helpful (well i have to try and error by building it though for better understanding).

Anyway, this is just me trying to visualise what the lib do.

The parser matches on slugs in between slashes (or rather, it's tokenized using slashes as delimiters). lit "bar" matches bar literally, not /bar. So given foo/bar/baz, the parser matches on tokens [ "foo", "bar", "baz" ]. Given /foo/bar/baz, the parser matches on tokens [ "", "foo", "bar", "baz" ], which is why you need lit "" to match the root slash.

i see.. so we need the lit "" only at the first time, not every / that we have..

And also it means, we cannot parse if there isn't any / in the address. For an example i want to parse like the following url:

https://matrix.hackage.haskell.org/#/package/a50#GHC-7.6/a50-0.2

as there is not / in between the a50 and GHC-70, the a50#GHC-7.6 will be tokenized as one string? How can we dealing with this case?

I think that https://matrix.hackage.haskell.org/#/package/a50#GHC-7.6/a50-0.2 would likely be tokenized as [ "", "package", "a50#GHC-7.6", "a50-0.2" ]. The parser does not recursively tokenize on #, it just drops everything until the first #.

@natefaubion noted and thank you..