I came across the following piece of code in the Sprache repository :
Parser<string> identifier =
from leading in Parse.WhiteSpace.Many()
from first in Parse.Letter.Once().Text()
from rest in Parse.LetterOrDigit.Many().Text()
from trailing in Parse.WhiteSpace.Many()
select first + rest;
var id = identifier.Parse(" abc123 ");
I see a contradiction here: the from
clause docs say the source (Parse.WhiteSpace.Many()
or Parse.Letter.Once().Text()
in our case) must be IEnumerable
:
The data source referenced in the from clause must have a type of
IEnumerable
,IEnumerable<T>
, or a derived type such asIQueryable<T>
But it isn't and the compiler says that's fine!
I thought there is some implicit cast to IEnumerable, but there isn't: Parse.WhiteSpace.Many()
returns Parser<IEnumerable<T>>
and Parse.Letter.Once().Text()
returns Parser<string>
(types are not IEnumerable
).
1st question: Why does the compiler allow this code?
Also, the final expression select first + rest
doesn't take into account leading
and trailing
variables, but the final result identifier
, for sure, uses them inside.
2nd question: By what rule\mechanism leading
and trailing
variables were added to the identifier
?
P.S. It'd be great if someone shared an all-encompassing doc about internal work of LINQ query syntax. I've found nothing on this topic.