2016-10-10 54 views
7

içinde Free Monad'lar ile keyfi ağaçlar kullanma Dilbilgisi için iki farklı yorumu olan bir kitaplık oluşturuyorum: 1) dilbilgisi tarafından tanımlanan dilde dizeler oluşturma dilbilgisi 2) dizeleri ayrıştırma.Scala + Cats

Kütüphane, gramerin AST'sini serbest bir monad olarak oluşturmak için kediler kullanır. Ancak, bu mükemmel uyumsuz gibi görünmeyebilir çünkü serbest monadlar AST'nin deyim listeleri için güzel bir liste benzeri temsilini oluşturur, ancak bir dilbilgisi bir açıklama listesinden çok uzaktır ve keyfi bir ağaç yapısına daha yakındır.

Ağaçlarımı, birleştirilen 2 dilbilgiyi belirtmek için ~ işlecini kullanarak gerçekleştirmeyi başardım. AST, o zaman kendilerinin keyfi AST'leri olan bir gramer listesidir.

Sorum şu: Bir AST'nin alttiplerini ücretsiz bir monada tekrarlamak için iyi bir yol nedir?

Benim şu anki uygulama is here:

def parserInterpreter: GrammarA ~> ParserInterpreterState = 
new (GrammarA ~> ParserInterpreterState) { 
    def apply[A](fa: GrammarA[A]): ParserInterpreterState[A] = 
    fa match { 
     case Regx(regexp) => parseRegex(regexp) 
     case Optional(b) => parseOptional(b.foldMap(this)) 
     case m @ Multi(g) => 
     def x: State[String, A] = 
      State.apply(state => { 
      g.foldMap(this) 
       .run(state) 
       .map { 
       case (s, ParseSuccess(_)) => x.run(s).value 
       case r @ (s, ParseFailure()) => (s, ParseSuccess(s).asInstanceOf[A]) 
       } 
       .value 
      }) 
     x 
     case Choice(a, b) => 
     State.apply(state => { 
      val runA = a.foldMap(this).run(state).value 
      if (runA._2.asInstanceOf[ParseResult[_]].isSuccess) 
      runA 
      else { 
      b.foldMap(this).run(state).value 
      } 
     }) 
    } 
} 

Not özellikle Multi vaka yinelemeli alt ağacı yorumlamak amacıyla güvensiz özyinelemeye (yani kuyruk değil özyinelemeli) kullandığını. Bunu yapmanın daha iyi bir yolu var mı?

Please click here for the source code.

cevap

0

Bir Ayrıştırıcı/Pretty yazıcı kütüphane inşa ediyoruz ise, manipüle edilmektedir nesnelerin muhtemelen monads değildir. Bunun yerine kedilerin 'InvariantMonoidal (ve ücretsiz conterpart, FreeInvariantMonoidal) kullanmak isteyebilirsiniz. İlgili eğitici, codec'lerde ilginç bulabileceğiniz a section'a sahiptir.