Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Better quotations #349

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
17 changes: 13 additions & 4 deletions kernel/src/main/scala/me/rexim/morganey/monad/package.scala
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
package me.rexim.morganey

import scala.collection.generic.CanBuildFrom
import scala.util.Try
import scala.language.higherKinds

package object monad {
/**
* Returns 'None', if one of the Options in 'lst' is 'None',
* otherwise the elements are collected in a 'Some'.
*/
def sequence[T](lst: List[Option[T]]): Option[List[T]] =
lst.foldRight(Option(List.empty[T])) {
case (ele, acc) => acc.flatMap(lst => ele.map(_ :: lst))
}
def sequence[CC[+T] <: TraversableOnce[T], T](lst: CC[Option[T]])
(implicit cbf: CanBuildFrom[Nothing, T, CC[T]]): Option[CC[T]] = {
var out = Option(cbf.apply())
val i = lst.toIterator
while (out.isDefined && i.hasNext)
i.next() match {
case Some(elem) => out.map(_ += elem)
case None => out = None
}
out.map(_.result())
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that it demands some additional tests. I understand the intention here to make it generic, but the implementation is too hard for me 😿


def sequence[T](lst: List[Try[T]]): Try[List[T]] =
lst.foldRight(Try(List.empty[T])) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,7 @@ trait TestTerms {
val zero = lnested(List("f", "x"), lvar("x"))
val one = lnested(List("f", "x"), lapp(lvar("f"), lvar("x")))
val two = lnested(List("f", "x"), lapp(lvar("f"), lapp(lvar("f"), lvar("x"))))

val `[0 .. 2]` = pair(zero, pair(one, pair(two, zero)))

}
9 changes: 9 additions & 0 deletions macros/src/main/scala/me/rexim/morganey/meta/DottedHole.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package me.rexim.morganey.meta

private[meta] object DottedHole {

def unapply(arg: String): Option[Int] =
if (arg startsWith "..") Hole.unapply(arg stripPrefix "..")
else None

}
2 changes: 0 additions & 2 deletions macros/src/main/scala/me/rexim/morganey/meta/Hole.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package me.rexim.morganey.meta

import java.util.regex.Pattern

private[meta] object Hole {

private val holePattern = "$hole"
Expand Down
5 changes: 2 additions & 3 deletions macros/src/main/scala/me/rexim/morganey/meta/Liftable.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ trait DefaultLiftableInstances {
implicit val liftInt = Liftable[Int](encodeNumber)
implicit val liftChar = Liftable[Char](c => encodeNumber(c.toInt))

implicit val liftString = Liftable[String] { s =>
val lift = implicitly[Liftable[Seq[Char]]]
implicit def liftString(implicit lift: Liftable[Seq[Char]]) = Liftable[String] { s =>
lift(s.toSeq)
}

Expand All @@ -25,7 +24,7 @@ trait DefaultLiftableInstances {
case (a, b) => encodePair( (liftA(a), liftB(b)) )
}

implicit def liftColl[X, CC[X] <: Traversable[X], A](implicit lift: Liftable[A]): Liftable[CC[A]] =
implicit def liftColl[CC[X] <: TraversableOnce[X], A](implicit lift: Liftable[A]): Liftable[CC[A]] =
Liftable[CC[A]] { xs =>
val ys = xs map lift
encodeList(ys.toList)
Expand Down
10 changes: 6 additions & 4 deletions macros/src/main/scala/me/rexim/morganey/meta/MetaParser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import me.rexim.morganey.ast._
import me.rexim.morganey.syntax.LambdaParser

/**
* Parser, which allows dollar signs as the start of identifiers,
* as special-marker for holes, which will be used during quotation
* of syntax nodes into another nodes.
* Special version of morganey's parser, that allows
* - two dots ('..') and
* - a dollar character ('$')
* as the start of identifiers, as special-markers for holes.
* Both markers will be used during quotation.
*/
object MetaParser extends LambdaParser {

override def variable: Parser[LambdaVar] =
"\\$?[a-zA-Z][a-zA-Z0-9]*".r ^^ LambdaVar
"((\\.\\.)?\\$)?[a-zA-Z][a-zA-Z0-9]*".r ^^ LambdaVar

}
Loading