Skip to content

Commit edbdff5

Browse files
committed
Λ syntax for polymorphic values.
Λ[A, B[_], ...](e) : T is rewritten to new T { def apply[A, B[_], ...] = e Note that explicit type `T` of the Λ-expression is required.
1 parent 3f0f156 commit edbdff5

2 files changed

Lines changed: 19 additions & 2 deletions

File tree

src/main/scala/Extractors.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,14 @@ trait Extractors {
4141
case _ => None
4242
}
4343
}
44+
object TermLambda {
45+
private val LambdaName = newTermName("Λ")
46+
47+
def unapply(tree: Tree): Option[(List[Tree], Tree)] = tree match {
48+
case Apply(TypeApply(Ident(name), tParams), body :: Nil) if name == LambdaName => Some((tParams, body))
49+
case _ => None
50+
}
51+
}
4452
object TermNuType {
4553
private val NuName = newTermName("ν")
4654

@@ -52,6 +60,9 @@ trait Extractors {
5260
object PolyVal {
5361
def unapply(tree: Tree): Option[(Tree, TermName, List[Tree], Tree)] = tree match {
5462

63+
// Λ[A, B, ...](e) : T
64+
case Typed(TermLambda(tParams, body), tpe) => Some((tpe, nme.apply, tParams, body))
65+
5566
// ν[T].method[A, B, ...](e)
5667
case Apply(TypeApply(Select(TermNuType(tpe), method), tParams), body :: Nil) => Some((tpe, method.toTermName, tParams, body))
5768

src/test/scala/polyval.scala

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,15 @@ class PolyVals {
3030
def functor: Functor[F]
3131
}
3232

33+
final class Fun[A, B](val run: A => B)
34+
3335
// universally quantified semigroup
3436
type SemigroupK[F[_]] = Forall[λ[α => Semigroup[F[α]]]]
3537

3638
// natural transformations
37-
type ~>[F[_] , G[_] ] = Forall [λ[α => F[α] => G[α]]]
38-
type ≈>[F[_[_]], G[_[_]]] = ForallK[λ[α[_] => F[α] => G[α]]]
39+
type ~>[F[_] , G[_] ] = Forall [λ[α => F[α] => G[α]]]
40+
type ≈>[F[_[_]], G[_[_]]] = ForallK[λ[α[_] => F[α] => G[α]]]
41+
type ~~>[F[_, _], G[_, _]] = Forall2[λ[(α, β) => F[α, β] => G[α, β]]]
3942

4043
// Const functor and constructors
4144
type ConstA[A] = Forall[Const[A, ?]]
@@ -61,13 +64,16 @@ class PolyVals {
6164
val monadToFunctor1 = ν[Monad ≈> Functor][F[_]](_.functor)
6265
val monadToFunctor2 = ν[Monad ≈> Functor].apply[F[_]]((m: Monad[F]) => m.functor)
6366

67+
val fun = Λ[A, B](new Fun(_)): Function1 ~~> Fun
68+
6469
val listFunctor = new Functor[List] {}
6570
val listMonad = new Monad[List] { def functor = listFunctor }
6671

6772
assert(headOption1[Int](List(1, 2)) == Some(1))
6873
assert(headOption2[Int](List(1, 2)) == Some(1))
6974
assert(monadToFunctor1[List](listMonad) == listFunctor)
7075
assert(monadToFunctor2[List](listMonad) == listFunctor)
76+
assert(fun[String, Int](_.length).run("foo") == 3)
7177
}
7278

7379
@Test

0 commit comments

Comments
 (0)