部分関数を使用して、空の入力引数を持つ関数を実装/オーバーライドしようとしています。これは、この機能しない最小限の例で最もよく説明されています。
trait T
trait TFactory {
def build(): T
}
class A(someParameter: Int) extends T
object A extends TFactory {
def build(someParameter: Int)(): T = new A(someParameter)
}
object creation impossible, since method build in trait TFactory of type ()T is not defined
ビルドのタイプが であるため、これは理にかなっています(Int)()T
。私の次のアイデアはbuild
、空の引数を取り、 a を返す関数に型を明示的に作成することでしたT
。
trait T
trait TFactory {
def build: () => T // what about empty parenthesis after build?
}
class A(someParameter: Int) extends T
object A extends TFactory {
def build(someParameter: Int): (() => T) = (() => new A(someParameter))
}
の型が であることは明らかbuild
です() => T
。驚いたことに、コンパイラは不平を言うようになりましobject creation impossible, since method build in trait TFactory of type => () => T is not defined
た (型が突然 a で始まることに注意してください=>
)。関数定義の最後に必死に空の括弧を追加しても役に立ちません。
これらの型が実際には同じであることをコンパイラに納得させるにはどうすればよいですか?
説明:
私の主な目標はT
、ファクトリのファクトリを必要とせずに、パラメータのない初期化を実現することです。例:
val t = A(33).build() // if this is possible, I though it might be possible to have:
val t = A.build(33)()
結論:
抽象関数は、関数が取る必要がある引数ブロックの数を単純に決定するため、不可能だと思いますbuild
。言い換えれば、関数によって抽象関数を実装することはできません。その部分適用は、実装しようとしている関数と同じ署名をたまたま持っています。