Created
November 24, 2021 21:35
-
-
Save jdegoes/3330177b555150525b36489c3131a596 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package spartan.training | |
object TheMonadProblem { | |
sealed trait Parser[+A] { self => | |
def map[B](f: A => B): Parser[B] = self.flatMap(a => Parser.succeed(f(a))) | |
def flatMap[B](f: A => Parser[B]): Parser[B] = Parser.FlatMap(self, f) | |
} | |
object Parser { | |
def succeed[A](a: A): Parser[A] = Succeed(a) | |
case object ParseChar extends Parser[Char] | |
final case class Succeed[A](value: A) extends Parser[A] | |
final case class Fail(message: String) extends Parser[Nothing] | |
final case class FlatMap[A, B](first: Parser[A], next: A => Parser[B]) extends Parser[B] | |
def compile[A](parser: Parser[A]): String => Either[String, A] = | |
parser match { | |
case ParseChar => ??? | |
case Succeed(value) => ??? | |
case Fail(message) => ??? | |
case FlatMap(first, next) => | |
val first1 = compile(first) | |
(input: String) => first1(input).flatMap(a => compile(next(a))(input)) | |
} | |
def describeGrammar[A](parser: Parser[A]): String = | |
parser match { | |
case ParseChar => "." | |
case Succeed(value) => "" | |
case Fail(message) => "" | |
case FlatMap(first, next) => ??? | |
} | |
def optimize[A](parser: Parser[A]): Parser[A] = ??? | |
} | |
} | |
object Avoidance { | |
sealed trait Parser[+A] { self => | |
def map[B](f: A => B): Parser[B] = Parser.Map(self, f) | |
def zip[B](that: Parser[B]): Parser[(A, B)] = Parser.Zip(self, that) | |
} | |
object Parser { | |
def succeed[A](a: A): Parser[A] = Succeed(a) | |
case object ParseChar extends Parser[Char] | |
final case class Succeed[A](value: A) extends Parser[A] | |
final case class Fail(message: String) extends Parser[Nothing] | |
final case class Map[A, B](first: Parser[A], f: A => B) extends Parser[B] | |
final case class Zip[A, B](first: Parser[A], second: Parser[B]) extends Parser[(A, B)] | |
def compile[A](parser: Parser[A]): String => Either[String, A] = | |
parser match { | |
case ParseChar => ??? | |
case Succeed(value) => ??? | |
case Fail(message) => ??? | |
case Map(first, f) => ??? | |
case Zip(first, next) => ??? | |
} | |
def describeGrammar[A](parser: Parser[A]): String = | |
parser match { | |
case ParseChar => "." | |
case Succeed(value) => "" | |
case Fail(message) => "" | |
case Map(first, f) => ??? | |
case Zip(first, next) => ??? | |
} | |
def optimize[A](parser: Parser[A]): Parser[A] = ??? | |
} | |
} | |
object Selectable { | |
sealed trait Parser[+A] { self => | |
def map[B](f: A => B): Parser[B] = Parser.Map(self, f) | |
def zip[B](that: Parser[B]): Parser[(A, B)] = Parser.Zip(self, that) | |
} | |
object Parser { | |
def succeed[A](a: A): Parser[A] = Succeed(a) | |
case object ParseChar extends Parser[Char] | |
final case class Succeed[A](value: A) extends Parser[A] | |
final case class Fail(message: String) extends Parser[Nothing] | |
final case class Map[A, B](first: Parser[A], f: A => B) extends Parser[B] | |
final case class Zip[A, B](first: Parser[A], second: Parser[B]) extends Parser[(A, B)] | |
final case class Select[A](predicate: Parser[Boolean], ifTrue: Parser[A], ifFalse: Parser[A]) extends Parser[A] | |
def select[A](p: Parser[Boolean])(ifTrue: Parser[A], ifFalse: Parser[A]): Parser[A] = Select(p, ifTrue, ifFalse) | |
def compile[A](parser: Parser[A]): String => Either[String, A] = | |
parser match { | |
case ParseChar => ??? | |
case Succeed(value) => ??? | |
case Fail(message) => ??? | |
case Map(first, f) => ??? | |
case Select(p, ifTrue, ifFalse) => ??? | |
case Zip(first, next) => ??? | |
} | |
def describeGrammar[A](parser: Parser[A]): String = | |
parser match { | |
case ParseChar => "." | |
case Succeed(value) => "" | |
case Fail(message) => "" | |
case Map(first, f) => ??? | |
case Select(p, ifTrue, ifFalse) => ??? | |
case Zip(first, next) => ??? | |
} | |
def optimize[A](parser: Parser[A]): Parser[A] = ??? | |
} | |
} | |
object Enumerable { | |
trait Enumerable[+A] { | |
def enumerate: List[A] | |
} | |
object Enumerable { | |
def enumerable[A](values: List[A]): Enumerable[A] = | |
new Enumerable[A] { | |
def enumerate: List[A] = values | |
} | |
implicit val enumerableBoolean: Enumerable[Boolean] = | |
enumerable(List(true, false)) | |
} | |
sealed trait Parser[A] { self => | |
def flatMap[B](f: A => Parser[B])(implicit e: Enumerable[A]): Parser[B] = | |
Parser.FlatMapFinite(e.enumerate, self, f) | |
def map[B](f: A => B): Parser[B] = Parser.Map(self, f) | |
def zip[B](that: Parser[B]): Parser[(A, B)] = Parser.Zip(self, that) | |
} | |
object Parser { | |
def succeed[A](a: A): Parser[A] = Succeed(a) | |
case object ParseChar extends Parser[Char] | |
final case class Succeed[A](value: A) extends Parser[A] | |
final case class Fail(message: String) extends Parser[Nothing] | |
final case class Map[A, B](first: Parser[A], f: A => B) extends Parser[B] | |
final case class Zip[A, B](first: Parser[A], second: Parser[B]) extends Parser[(A, B)] | |
final case class FlatMapFinite[A, B](values: List[A], first: Parser[A], f: A => Parser[B]) extends Parser[B] | |
} | |
} | |
object Expressible { | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment