-1

我想在java中編寫一些函子,monads和applicatives。我找到了一些,並選擇了下面的一個。這個應用函數定義中的get()和unit()是什麼?

在術語類別理論中,什麼是get()返回?

單位()似乎是某種身份,但從什麼到什麼?或者也許這是一個構造函數?

我看到了one有一個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

一些Haskell可能會有幫助。首先,函子:

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

我們可以看這是說,如果一個類型fFunctor那麼就必須有一個fmap功能,這需要a -> b類型的功能和價值OIF型f a,得到f b 。即該類型允許將該函數應用於其中的值。

Java沒有對高kinded類型,這將需要定義如上一個仿函數類型的支持,所以我們反而要接近它:

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

這裏泛型類型參數F是Functor類型,相當於Haskell定義中的f,而T是包含的類型(與U相同),相當於Haskell定義中的a(和b)。在沒有HKT的情況下,我們必須使用通配符來表示函子類型(? extends Functor6<F, T>)。

接着,應用型:

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

即,對於一個類型f是一個應用性它必須是一個算符,具有pure操作該升降機一個值到應用性f,和一個應用操作(<*> ),其中給定f內的函數(a -> b)和f內的a,可以將該函數應用於該值以在f內產生b

這是你的Java等效,使用一些Java 8層的功能簡化,並與一些類型的修正:

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)); 
     }; 
    } 
} 

如果我們把它一行一行:

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

說,一個應用型是仿函數。這:

T get(); 

似乎是獲得應用程序中的值的方法。這可能適用於特定情況,但通常不起作用。這個:

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

應該等同於Haskell定義中的pure函數。它應該是靜態的,否則爲了能夠調用它而需要一個應用價值,但是使其成爲靜態的將防止它在實際的應用實現中被覆蓋。在Java中沒有簡單的方法來解決這個問題。

然後,你有apply方法,其中權利應該相當於在Haskell中的<*>。正如我們所看到的,它只是從應用程序和其參數中獲取函數f,並返回包含將函數應用於參數的結果的應用程序。

這是車輪真正脫落的地方。應用程序如何將一個函數應用於某個值的細節對每個應用程序都是特定的,不能像這樣泛化。

總之,這種做法是錯誤的。這並不是說你不能在Java中實現應用函數 - 你可以並且很容易,但是你不能做的是在語言中聲明它們是應用的,就像你可以在Haskell中使用類型類一樣。

相關問題