-1

私はいくつかのファンクション、モナド、およびアプリケーションをjavaでコーディングしようとしています。私はいくつかを見つけて、以下のものを選んだ。このアプリケーションファンクタの定義では、get()とunit()は何ですか?

カテゴリ理論では、get()は何を返していますか?

ユニット()は何らかのアイデンティティーのように思えますが、何から何に変わりますか?あるいは、これはコンストラクタですか?

私はを見ました。 get()を持つファンクタの定義です。これは何を返すだろうか?

abstract class Functor6<F,T> { 
    protected abstract <U> Function<? extends Functor6<F,T>,? extends Functor6<?,U>> fmap(Function<T,U> f); 
} 

abstract class Applicative<F,T>extends Functor6<F,T> { 
    public abstract <U> U get(); // what is this in terms of category theory? 

    protected abstract <U> Applicative<?,U> unit(U value); // what is this in terms of category theory? 

    protected final <U> Function<Applicative<F,T>,Applicative<?,U>> apply(final Applicative<Function<T,U>,U> ff) { 
     return new Function<Applicative<F,T>,Applicative<?,U>>() { 
      public Applicative<?,U> apply(Applicative<F,T> ft) { 
       Function<T,U> f=ff.get(); 
       T t=ft.get(); 
       return unit(f.apply(t)); 
      } 
     }; 
    } 
} 

答えて

1

ハスケルが役立ちます。まず、ファンクタ:

class Functor f where 
    fmap :: (a -> b) -> f a -> f b 

我々はタイプfFunctorであるならば、f bを生成するタイプf a OIFタイプa -> bと値の関数を取るfmap機能を、そこに持っている必要があります言うように、これを読むことができます。私。タイプによって、その中の値に関数を適用することができます。

Javaは、上記のようにファンクタの型を定義するために必要とされるであろう高kinded種類のサポートを持っていないので、代わりに私たちはそれを近似する必要があります。

ここ
interface Functor6<F, T> { 
    <U> Function<? extends Functor6<F, T>, ? extends Functor6<?, U>> fmap(Function<T, U> f); 
} 

ジェネリック型パラメータFをされますHaskellの定義ではfに相当するFunctorタイプであり、Tは、含まれるタイプ(U)で、Haskell定義のa(およびb)に相当します。 HKTが存在しない場合、ファンクタタイプ(? extends Functor6<F, T>)を参照するためにワイルドカードを使用する必要があります。

次に、Applicativeの:

class (Functor f) => Applicative f where 
    pure :: a -> f a 
    <*> :: f (a -> b) -> f a -> f b 

すなわちタイプfそれはファンクタでなければならない応用的であるために、応用的fに値を持ち上げるpure操作を有し、動作を適用する(<*>fの中にfの中に関数(a -> b)があり、fの中にaがある場合、その値に関数を適用して、の中にbを得ることができます。

はここにいくつかのJava 8つの機能を使用して単純化して、Javaと同等、だ、といくつかの種類が修正されて:

interface Applicative<F, T> extends Functor6<F, T> { 

はApplicativeのが関数子で言う:

interface Applicative<F, T> extends Functor6<F, T> { 
    T get(); 

    <F, U> Applicative<F, U> unit(U value); 

    default <U> Function<Applicative<F, T>, Applicative<F, U>> apply(Applicative<?, Function<T, U>> ff) { 
     return ft -> { 
      Function<T, U> f = ff.get(); 
      T t = ft.get(); 
      return unit(f.apply(t)); 
     }; 
    } 
} 

我々は行ずつそれを取る場合。これは:

T get(); 

は、アプリケーション内の値にアクセスする手段であるようです。これは特定のケースでは機能しますが、一般的には機能しません。これは、ハスケル定義のpure関数と等価であると考えられます。それは静的でなければなりません。そうでなければ、呼び出すためには適用可能な値が必要ですが、それを静的にすると、実際に適用される実装では上書きされません。これをJavaで簡単に解決する方法はありません。

次に、applyメソッドがあります。このメソッドは、Haskellの<*>と同等の権利があります。わかるように、関数fを適用してからその引数を取り出し、その関数を引数に適用した結果を含むアプリケーションを返します。

これは、車輪が実際に外れる場所です。申請者がどのように値に関数を適用するかの詳細は、各アプリケーションに固有であり、このように一般化することはできません。要するに、このアプローチは間違っています。これは、Javaでアプリケーションファンクタを実装できないと言っているわけではありません。あなたはできますが、それは簡単ですが、ハスケル(型クラスを使用する)のように、アプリケーションの言語内の状態です。

関連する問題