Scala 2.12:对于普遍量化的SAM特征,Java 8方法参考的等价物是什么?

时间:2016-09-06 19:42:05

标签: java scala java-8 scala-2.12

我的目标是通过SAM(单一抽象方法)特征的新scala 2.12支持来实现代数数据类型(教会编码)的单例值。

在Java中,以下程序返回true

import java.util.function.Function;
import java.util.function.Supplier;

@FunctionalInterface
public interface Maybe<A> {

  <X> X fold(Supplier<X> empty, Function<A, X> just);

  static <A, X> X empty0(Supplier<X> empty, Function<A, X> just) {
    return empty.get();
  }

  static <A> Maybe<A> empty() {
      return Maybe::empty0;
  }

  static void main(String[] args) {
    Maybe<?> emptyString = Maybe.<String>empty();
    Maybe<?> emptyInt = Maybe.<Integer>empty();

    System.out.println(emptyString == emptyInt); // print "true".
  }
}

我试图将此编码移植到scala 2.12,但它没有编译:

@FunctionalInterface
trait Maybe[A] {
  def fold[X](empty: => X, just: A => X): X
}

object Maybe {
  def empty0[A, X](empty: => X, just: A => X): X = empty

  def empty[A]: Maybe[A] = empty0(_ ,_) // does not compile

  def main(args: Array[String]): Unit = {
    val emptyString: Maybe[String] = Maybe.empty
    val emptyInt: Maybe[Integer] = Maybe.empty

    print(emptyString eq emptyInt) // how to make this print "true"???
  }
}

我得到的错误是: missing parameter type for expanded function ((x$1: <error>, x$2: <error>) => empty0(x$1, x$2))

我的目标是让scalac触发Javac完成的相同优化,使java程序打印&#34; true&#34;。只要它不使用asInstanceOfNothing / variance注释,我愿意接受满足scalac所需的一切。

编辑:由于目前不支持,我为此打开了feature request on the scala issue tracker(请投票支持!; - )。

1 个答案:

答案 0 :(得分:3)

不幸的是,根据the specification

,这是不允许的
  

由此得出:

     
      
  • 如果C类定义了一个构造函数,它必须是可访问的,并且必须只定义一个空的参数列表;

  •   
  • m不能是多态的;

  •   
  • 必须可以通过推断C的任何未知类型参数从S派生完全定义的类型U.

  •