Proposed implementation of 'unlift' on Function1, the inverse

function of PartialFunction#lift.  Review by rytz and other
interested parties.  References #3825, but not closing until this
is further considered.

git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@22963 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
This commit is contained in:
extempore 2010-09-09 17:05:40 +00:00
parent 18f36af1d1
commit 605407a6bd
93 changed files with 152 additions and 94 deletions

View File

@ -153,6 +153,18 @@ object FunctionOne extends Function(1) {
/** (f andThen g)(x) == g(f(x))
*/
def andThen[A](g: R => A): T1 => A = { x => g(apply(x)) }
/** Turns a function A => Option[B] into a PartialFunction[A, B].
* @see PartialFunction#lift
* @return a partial function which is defined for those inputs
* where this function returns Some(_) and undefined where
* this function returns None.
*/
def unlift[R1](implicit ev: R <:< Option[R1]): PartialFunction[T1, R1] = new PartialFunction[T1, R1] {
def apply(x: T1): R1 = ev(Function1.this.apply(x)).get
def isDefinedAt(x: T1): Boolean = Function1.this.apply(x).isDefined
override def lift = Function1.this.asInstanceOf[T1 => Option[R1]]
}
"""
}
@ -314,6 +326,7 @@ import scala.collection.generic.CanBuildFrom
class Zipped[+Repr1, +El1, +Repr2, +El2](coll1: TraversableLike[El1, Repr1], coll2: IterableLike[El2, Repr2]) { // coll2: IterableLike for filter
def map[B, To](f: (El1, El2) => B)(implicit cbf: CanBuildFrom[Repr1, B, To]): To = {
val b = cbf(coll1.repr)
b.sizeHint(coll1)
val elems2 = coll2.iterator
for(el1 <- coll1)

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010 (with fancy comment)
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010 (with fancy comment)
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010 (with fancy comment) (with extra methods)
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010 (with fancy comment) (with extra methods)
package scala
@ -46,5 +46,20 @@ trait Function1[@specialized(scala.Int, scala.Long, scala.Float, scala.Double) -
/** (f andThen g)(x) == g(f(x))
*/
def andThen[A](g: R => A): T1 => A = { x => g(apply(x)) }
/** Turns a function A => Option[B] into a PartialFunction[A, B]. Important note:
* this transformation implies the original function will be called 2 or more
* times on each logical invocation, because the only way to supply an implementation
* of isDefinedAt is to call the function and examine the return value.
*
* @see PartialFunction#lift
* @return a partial function which is defined for those inputs
* where this function returns Some(_) and undefined where
* this function returns None.
*/
def unlift[R1](implicit ev: R <:< Option[R1]): PartialFunction[T1, R1] = new PartialFunction[T1, R1] {
def apply(x: T1): R1 = ev(Function1.this.apply(x)).get
def isDefinedAt(x: T1): Boolean = Function1.this.apply(x).isDefined
override def lift = Function1.this.asInstanceOf[T1 => Option[R1]]
}
}

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010 (with extra methods)
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010 (with extra methods)
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010 (with extra methods)
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010 (with extra methods)
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010 (with extra methods)
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010 (with extra methods)
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010 (with extra methods)
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010 (with extra methods)
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010 (with extra methods)
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010 (with extra methods)
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010 (with extra methods)
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010 (with extra methods)
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010 (with extra methods)
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010 (with extra methods)
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010 (with extra methods)
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010 (with extra methods)
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010 (with extra methods)
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010 (with extra methods)
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010 (with extra methods)
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010 (with extra methods)
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010 (with fancy comment) (with extra methods)
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010 (with fancy comment) (with extra methods)
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010 (with extra methods)
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010 (with extra methods)
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010 (with extra methods)
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010 (with extra methods)
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010 (with extra methods)
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010 (with extra methods)
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010 (with extra methods)
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010 (with extra methods)
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010 (with extra methods)
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010 (with extra methods)
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010 (with extra methods)
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010 (with extra methods)
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010 (with extra methods)
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010 (with extra methods)
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010 (with extra methods)
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010 (with extra methods)
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010 (with extra methods)
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010 (with extra methods)
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010 (with extra methods)
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010 (with extra methods)
package scala

View File

@ -59,10 +59,15 @@ trait PartialFunction[-A, +B] extends (A => B) {
}
/** Turns this partial function into an plain function returning an `Option` result.
* @see Function1#unlift
* @return a function that takes an argument `x` to `Some(this(x))` if `this`
* is defined for `x`, and to `None` otherwise.
*/
def lift: A => Option[B] = { x => if (isDefinedAt(x)) Some(this(x)) else None }
def lift: A => Option[B] = new (A => Option[B]) {
def apply(x: A): Option[B] = if (isDefinedAt(x)) Some(PartialFunction.this.apply(x)) else None
override def unlift[R1](implicit ev: Option[B] <:< Option[R1]): PartialFunction[A, R1] =
PartialFunction.this.asInstanceOf[PartialFunction[A, R1]]
}
}
/** A few handy operations which leverage the extra bit of information

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,11 +7,11 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010 (with extra methods)
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010 (with extra methods)
package scala
import scala.collection.{TraversableLike, IterableLike, IndexedSeqLike}
import scala.collection.{TraversableLike, IterableLike}
import scala.collection.generic.CanBuildFrom
@ -56,6 +56,7 @@ case class Tuple2[@specialized(Int, Long, Double) +T1, @specialized(Int, Long, D
val b = cbf(coll1.repr)
b.sizeHint(coll1)
val elems2 = coll2.iterator
for(el1 <- coll1)
if(elems2.hasNext)
b += f(el1, elems2.next)

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010 (with extra methods)
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010 (with extra methods)
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala

View File

@ -6,9 +6,8 @@
** |/ **
\* */
// $Id$
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala.runtime

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala.runtime

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala.runtime

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala.runtime

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala.runtime

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala.runtime

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala.runtime

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala.runtime

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala.runtime

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala.runtime

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala.runtime

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala.runtime

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala.runtime

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala.runtime

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala.runtime

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala.runtime

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala.runtime

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala.runtime

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala.runtime

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala.runtime

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala.runtime

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala.runtime

View File

@ -7,7 +7,7 @@
\* */
// generated by genprod on Thu Apr 29 17:52:16 CEST 2010
// generated by genprod on Thu Sep 09 09:06:40 PDT 2010
package scala.runtime

View File

@ -0,0 +1,25 @@
object Test {
def evens1(x: Int) = if (x % 2 == 0) Some(x) else None
def evens2: PartialFunction[Int, Int] = {
case x if x % 2 == 0 => x
}
def main(args: Array[String]): Unit = {
val f1 = evens1 _
val f2 = evens2.lift
assert(1 to 10 forall (x => f1(x) == f2(x)))
val f3 = f1.unlift
val f4 = f2.unlift
assert(1 to 10 forall { x =>
if (!f3.isDefinedAt(x)) !f4.isDefinedAt(x)
else f3(x) == f4(x)
})
assert(f1 eq f3.lift)
// Hmm, why is this not true:
// assert(f2 eq f4.lift)
}
}