应用函子的这个定义中的 get() 和 unit() 是什么?

What are get() and unit() in this definition of applicative functor?

我正在尝试在 java 中编写一些函子、单子和应用程序。我找到了一些并选择了下面的那个。

就类别理论而言,get() 返回什么?

unit() 看起来像是某种身份,但从什么到什么?或许这是构造函数?

我看到 一个 具有 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));
            }
        };
    }
}

一些 Haskell 可能会有所帮助。首先,一个函子:

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

我们可以理解为如果一个类型 f 是一个 Functor 那么必须有一个 fmap 函数,它接受一个类型为 a -> b 的函数并且一个值 oif 类型 f a 产生一个 f b。 IE。该类型允许将函数应用于其中的值。

Java 不支持更高种类的类型,这将需要像上面那样定义一个函子类型,所以我们必须近似它:

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

这里的泛型类型参数F是Functor类型,相当于Haskell定义中的fT是包含的类型(和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,可以将该函数应用于 yield 的值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> {

表示 Applicative 是 Functor。这个:

    T get();

似乎是一种获取应用程序中的值的方法。这可能适用于特定情况,但一般情况下不起作用。这个:

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

应该等同于 Haskell 定义中的 pure 函数。它应该是静态的,否则您需要一个应用值才能调用它,但是将其设为静态会阻止它在实际的应用实现中被覆盖。在 Java.

中没有简单的方法来解决这个问题

然后你有 apply 方法,根据权利应该等同于 Haskell 中的 <*>。正如我们所看到的,它只是从应用程序中获取函数 f,然后是它的参数,returns 一个包含将函数应用于参数的结果的应用程序。

这才是轮子真正脱落的地方。应用程序如何将函数应用于值的详细信息对于每个应用程序都是特定的,不能像这样概括。

总之,这种做法是错误的。这并不是说你不能在 Java 中实现应用函子——你可以而且很容易,但你不能做的是在语言中声明它们是应用函子,就像你在 [=77 中所做的那样=](使用类型 类)。