-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中使用类型类一样。

相关问题