Reputation: 5510
I'm trying to understand this code from url-parser
:
route : Url.Parser (Route -> a) a
route =
Url.oneOf
[ Url.map Home top
, Url.map BlogList (s "blog" <?> stringParam "search")
, Url.map BlogPost (s "blog" </> int)
]
Is it: "route
is a function that takes 1) a Parser
, 2) a function that takes a Route
and returns an a
, and 3) an a
"?
This doesn't seem correct because if it's just listing the arguments, where is it expressing the return value of route
itself?
I'm very new to elm, but what throws me off here is that the ->
is contained within the parens, and then there's no ->
at the end indicating what route
returns.
Upvotes: 1
Views: 100
Reputation: 1676
The easy answer is that route
here is not really a function, but a constant: it represents a particular kind of Parser
.
Now this, of course, raises the more difficult question of what kind of parser does it represent?
And that is a rather tricky one. I believe having some background on parser combinators could probably help here (https://en.wikipedia.org/wiki/Parser_combinator).
But either way, it took me a while and I might still be getting it wrong. These are the steps I went through:
Parser
. You can execute it using parsePath
or parseHash
. Each of which promising that if you provide a Parser
of type Parser (a->a) a
(where a
is a generic type variable) then it will turn a Location
into a Maybe a
string
for instance is a Parser (String -> a) a
, while int
is Parser (Int -> a) a
.</>
, which is Parser a b -> Parser b c -> Parser a c
. If you write string </> int
, you will get a Parser (String -> Int -> c) c
. This is possible, because the type variable in string
can be substituted as Int -> c
, so it becomes Parser (String -> Int -> c) (Int -> c)
.Parser a b
represents a parser that can parse part of a complex a
to reduce it to a simpler b
.Route
you must define a Parser (Route -> a) a
to be able to turn the url into your internal representation. If one of your constructors for Route
is something like MyTwoParamsRoute String Int
, then you will first need to define myTwoParamsParser : Parser (String -> Int -> a) a
using some of the combinators (</>
or <?>
) and then use map MyTwoParamsRoute myTwoParamsParse
to actually apply the constructor function.So the long answer to your original question: route : Parser (Route -> a) a
represents a parser which can parse a Route
out of some string (typically either the hash or the path part of the url) -- while offering the possibility that once the string is reduced by whatever Route
represents, the remainder can be further parsed by a different parser.
Upvotes: 1
Reputation: 4968
Since you see just the function name before the =
in route =
, it means that it takes no arguments.
You can also see that in the annotation since there's no ->
.
There is one inside parenthesis.
route
therefore, returns a Url.Parser (Route -> a) a
.
From what I understand, it returns a type Parser a b
where a
is a function (Route -> a)
and b
can be anything ( it's named a
here, but it's irrelevant ).
The ->
is referring to that function that the type Parser
"encapsulates".
I don't know how to explain it better, but take a look at the library functions. They work in a similar way
http://package.elm-lang.org/packages/evancz/url-parser/2.0.1/UrlParser
Upvotes: 0