我有一个带有返回函数对象的方法的类。要求是方法是arity 0并且它的返回类型是Function0的Option - 其返回类型是原始返回类型。例如:
class MyClass {
def f(): Option[Function[A]] = Some(g _)
def g(): Option[Function[A]] = Some(h _)
... goes on and on, eventually returns Some(z _) ...
def z(): Option[Function[A]] = None
}
由于递归,问题是类型A被定义为:
type A = Option[Function0[A]]
但由于不允许循环引用,因此会产生错误:
illegal cyclic reference involving type A
我显然想避免为每个方法定义不同的返回类型,但由于循环,似乎不可能使用统一的返回类型。有没有办法做到这一点?谢谢!
答案 0 :(得分:3)
Scala类型定义不支持此功能。见How to define a cyclic type definition?
您可以使用类而不是类型来完成此操作,但您必须定义自己的类似于类的类。下面是一个例子(省略了monadic方法)。另请参阅此邮件列表讨论:http://www.scala-lang.org/node/2541
sealed trait OptionalFunction extends (() => OptionalFunction) {
def get: (() => OptionalFunction)
}
case class SomeFunction(fn: () => OptionalFunction) extends OptionalFunction {
def apply() = fn()
def get = fn
}
case object NoFunction extends OptionalFunction {
def apply() = this
def get = throw new NoSuchElementException
}
class MyClass {
type A = OptionalFunction
def f(): A = SomeFunction(g _)
def g(): A = SomeFunction(h _)
def h(): A = SomeFunction(() => { println("At the end!"); i })
def i(): A = NoFunction
}
scala> new MyClass().f()()()()
At the end!
res0: OptionalFunction[Unit] = <function0>
答案 1 :(得分:0)
我不确定这是否是你正在寻找的东西,但是许多这些边缘情况可以通过显式使用对象来解决:
abstract class F extends Function0[F]
val p = new F {
def apply() = { println("hi"); this }
}
>> defined class F
>> p: $anon forSome { type $anon <: F{def apply(): $anon} } =
p()
>> hi
>> res2: $anon =
p()()
>> hi
>> hi
>> res3: $anon =
快乐的编码。