2017-07-26 6 views
9

私はYコンビネータの問題を解決しました。今は、ジェネリックパラメータを再帰的に参照することができないことがわかりました。例えば汎用パラメータを再帰的に参照するには?

Y = λf.(λx.f (x x)) (λx.f (x x)) 

IntUnaryOperator fact = Y(rec -> n -> n == 0 ? 1 : n * rec.applyAsInt(n - 1)); 

IntUnaryOperator Y(Function<IntUnaryOperator, IntUnaryOperator> f) { 
    return g(g -> f.apply(x -> g.apply(g).applyAsInt(x))); 
} 

IntUnaryOperator g(G g) { 
    return g.apply(g); 
} 

//  v--- I want to remove the middle-interface `G` 
interface G extends Function<G, IntUnaryOperator> {/**/} 

Q:どのように私は、追加のインタフェースGを導入することを避けるために方法g上の一般的なパラメータを使用することができ、そして一般的なパラメータがUNCHECKED警告を回避する必要がありますか?

ありがとうございます。

+2

私はそれが不可能だと確信しています。 Javaでは、特定の汎用パラメータが機能インタフェースAFAIKであることを要求する方法はありません。 – Ryan

答えて

4

あなたは動作しませんどのような再帰的な型定義

<G extends Function<G, IntUnaryOperator>> IntUnaryOperator g(G g) { 
    return g.apply(g); 
} 

とジェネリックメソッドを宣言することができ、Gにラムダ式を割り当て、ラムダ式でこのメソッドを呼び出すことです。 The specification

15.27.3と言います。ラムダ式

ラムダ式のタイプは、Tは、機能インタフェースタイプである場合(§9.8)...

Gが割り当てコンテキスト、呼び出しコンテキスト、またはターゲット型Tとコンテキストを鋳造で互換性があります機能的なインタフェースではなくタイプパラメータです。Gの実際のインタフェースタイプを推論する方法はありません。まだ動作

、あなたはラムダ式の実際のインタフェースG使用する場合:

IntUnaryOperator Y(Function<IntUnaryOperator, IntUnaryOperator> f) { 
    return g((G)g -> f.apply(x -> g.apply(g).applyAsInt(x))); 
} 

// renamed the type parameter from G to F to avoid confusion 
<F extends Function<F, IntUnaryOperator>> IntUnaryOperator g(F f) { 
    return f.apply(f); 
} 

// can't get rid of this interface 
interface G extends Function<G, IntUnaryOperator> {/**/} 

または

IntUnaryOperator fact = Y(rec -> n -> n == 0 ? 1 : n * rec.applyAsInt(n - 1)); 

IntUnaryOperator Y(Function<IntUnaryOperator, IntUnaryOperator> f) { 
    return this.<G>g(g -> f.apply(x -> g.apply(g).applyAsInt(x))); 
} 

// renamed the type parameter from G to F to avoid confusion 
<F extends Function<F, IntUnaryOperator>> IntUnaryOperator g(F f) { 
    return f.apply(f); 
} 

// can't get rid of this interface 
interface G extends Function<G, IntUnaryOperator> {/**/} 

をだから、方法gインターフェイスGへの依存関係のないと総称ですが、インタフェースはラムダ式のターゲット型として使用する必要があります。

+0

はい、私はちょうどタイプ変数が再帰的に参照できることがわかりました。問題はλ式で発生します。大変感謝しています。例えば ​​'g(null)'は正常に動作しますが、 'g(g - > null)'はうまく動作しません。 –

関連する問題