Convert our parser into Monad

Source: Internet
Author: User

Remember our last delegate type of parser, before starting this article, we strongly recommend that you review this parser definition

 Public Delegate Maybe<tuple<t,string>>Parser<T> (string input)

Remember how hard it was for us to combine these parser? Now that we've converted parser to monad in a new way, we've learned how to convert generic and generic interfaces to Monad, and you can also convert delegates to Monad

First we implement a Toparser method, which is fairly simple and returns only one parser that does not consume any input string.

 Public Static Parser<t>toparser ( this T value) {return input=>new just<tuple<t, string>>(tuple.create (value,input))}

Next we need a bind method that recalls the signature of the Bind method, remembering all the same Monad bind method signatures.

public static parser<b> bind<a,b> (this parser<a>a, Func<a,parser<b>>func) ()

Now we step into bind, first look at the return type Parser<b> Remember that parser<b> is a parameter that returns a function of type maybe<tuple<b,string>> with a string. So we need to return a lambda expression for this function

 Public Static Parser<b>bind<a,b> ( This parser<a> A, func<a,parser<b>func>) {input = ={//... }}

This lambda needs to return maybe<tuple<b,string>> we can return parser<b> by calling Func, and then calling Parser<b> to return it:

 Public Static Parser<b>bind<a,b> ( This parser<a>a, func<a,parser<b>>Func) {  Return input=>{var bparser=func (??? ); return Bparser (??? );};}

We need a parameter a called Func, we can call a to get its return value and then take a from it:

 Public StaticParser<b> bind<a,b> ( ThisParser<a>a, func<a,parser<b>>func) { returnInput=>{ varAmaybe=a (input);varAresult=amaybe asJust<tuple<a,string>>; //Short circuit If parse failsif(Aresult = =NULL)return NewNothing<tuple<b,string>>();varAvalue=aResult.Value.Item1;varBparser=func (avalue);returnBparser (???);}}

Note that we shorted out the parsing process, if there is a parser failure, this means that any parser combination will return nothing if one of the parsers cannot resolve its input.

Finally we need a string as the input to the Bparser, which can be obtained from the return result of parser a:

 Public StaticParser<b> bind<a,b> ( ThisParser<a>a, func<a,parser<b>>func) {  returnInput=>{  varAmaybe=a (input);varAresult=amaybe asJust<tuple<a,string>>; //Short circuit If parse failsif(Aresult = =NULL)return NewNothing<tuple<b,string>>();varAvalue=aResult.Value.Item1;varsstring=aResult.Value.Item2;varBparser=func (avalue);returnBparser (sstring);}}

We have created a Monad parser, in order to use LINQ syntax, we need to implement SelectMany,

Now we can implement our Hello World parser with just the following three lines of code.

 Public Static Parser<c>selectmany<a,b,c> ( This parser<a>a, Func<a,parser<b>>func, Func <A,B,C>Select) {a.bind (Aval=>func (aval). Bind (bval=>Select(aval,bval). Toparser ()));}

varHelloworldparser= fromHelloinch "Hello". Find () fromWorldinch " World". Find ()Select New(Hello=hello, world=World );varResult=helloworldparser ("HelloWorld"); Console.WriteLine (Result. Asstring (x=X.hello)); Console.WriteLine (Result. Asstring (x=x.world));//outputs//Hello// World

This implementation is full of beauty and hopefully you can start to understand how to create complex logic with monad, and if you want to learn more about Monad parser, the Nicholas Blumhardt implementation of project Sprache is for reference: https://github.com /sprache/sprache

Other Monad Resources reference:

Https://github.com/phenixyu/csharp-monad

Convert our parser into Monad

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.