编程语言
首页 > 编程语言> > 这是monad(在Java中)吗?

这是monad(在Java中)吗?

作者:互联网

在我声称自己已经钉牢之前,我想问一下.请不要退缩,我想首先在这里遇到任何批评.

由于Java缺乏动态语言传递任意参数所具有的灵活性,因此我通过将所有可能的输入捆绑到一个类(人)中来进行补偿,该类构成了输入空间.这些函数在monad的帮助下将其映射到输出空间(Friends).

我并不是要解决一般情况,只是想出一个例子来了解我是否了解设计模式.

单子(如果是这样)将执行以下规则:邀请被拒绝或出现错误后,将不再进行进一步处理.

对不起,长度.毕竟是Java.为了节省空间,我采用了一些约定的捷径.

这实际上是单子的例子吗? (封装在Friends类中)

public class Sample {
    public static void main(String[] args) {
        People people0 = new People("Bob", "Fred");
        Friends friends0 = Friends.pipeline(people0, ToFromFunction.INVITE, ToFromFunction.ACCEPT);
        System.err.println(friends0);

        People people1 = new People("Bob", "Jenny");
        Friends friends1 = Friends.pipeline(people1, ToFromFunction.INVITE, ToFromFunction.ACCEPT);
        System.err.println(friends1);

        People people2 = new People("Bob", "Fred");
        Friends friends2 = Friends.pipeline(people2, ToFromFunction.INVITE, ToFromFunction.BLOCK);
        System.err.println(friends2);
    }
}

/** this is the space of all inputs */
public class People {
    public People(String from, String to) {
        this.from = from;
        this.to = to;
    }

    public String from;
    public String to;
}

/** this is the output space, and the monad (?) */
public class Friends {

    public boolean friends = false;
    public boolean rejected = false;
    public String errors = "";

    public static Friends unit(People from) {
        return new Friends();
    }

    public Friends bind(ToFromFunction f, People from) {
        if (! errors.isEmpty()) {
            // we have errors; skip the rest
            return this;
        }

        if (rejected) {
            // No means no
            return this;
        }

        return f.act(from, this);
    }

    public static Friends pipeline(People from, ToFromFunction... functions) {
        Friends result = Friends.unit(from);
        for (ToFromFunction f : functions) {
            result = result.bind(f, from);
        }
        return result;
    }
}

/** functions from People to Friends */
public interface ToFromFunction {

    Friends act(People from, Friends to);

    ToFromFunction INVITE = new ToFromFunction() {
        public Friends act(People from, Friends to) {
            // Jenny has blocked Bob
            if ("Jenny".equals(from.to) && "Bob".equals(from.from)) {
                to.errors = "Jenny blocked Bob";
            }
            return to;
        }
    };

    ToFromFunction ACCEPT = new ToFromFunction() {
        public Friends act(People from, Friends to) {
            // Good to go!
            to.friends = true;
            return to;
        }
    };

    ToFromFunction BLOCK = new ToFromFunction() {
        public Friends act(People from, Friends to) {
            to.friends = false;
            to.rejected = true;
            return to;
        }
    };
}

解决方法:

Monad是Type,它实现具有固定签名的两个功能:unit和bind.

用Haskell表示法:

unit :: a -> m a

bind :: m a -> (a -> m b) -> m b

unit将对象从类型a包装到类型a的m中. a的类型必须是任意的.绑定的实现可以是任何东西(但必须满足单子法则).

让我们尝试将您的示例转换为Haskell语法:

人们只是一个元组:

type People = (String, String)

Friends的类型是两个布尔值和一个String的三元组.

如果我们使用这些类型,那么您的Friends.unit方法就是这样:

unit_friends :: People -> Friends
unit_friends _ = (false, false)

这意味着,unit_friends正在丢弃is参数,而只是返回一个新的Friends实例.这是单元的错误类型签名.相反,单元应具有以下类型签名:

unit_friends :: a -> Friends a

在Java中,这看起来类似于:

public static Friends<T> unit(T from) {
    // return something of type Friends<T>
}

您的bind函数采用ToFromFunction类型的函数和People类型的对象,并返回Friends类型的东西:

bind_friends :: ToFromFunction -> People -> Friends

让我们将ToFromFunction替换为

type ToFromFunction = People -> Friends -> Friends

因为那是行为的类型特征.

bind_friends :: (People -> Friends -> Friends) -> People -> Friends

让我们翻转bind_friends的参数,因为lambda函数应该是第二个参数:

bind_friends :: People -> (People -> Friends -> Friends) -> Friends

但是它应该具有以下类型签名:

bind_friends :: Friends a -> (a -> Friends b) -> Friends b

您的单位和绑定类型与真正的单子类型不匹配,但这有点接近.

让我们忘记一下,我们需要一个任意类型a. bind_friends的第一个参数必须是Friends类型,而不是People类型,因为bind应该将ToFromFunction提升为Friends monad.

标签:monads,java
来源: https://codeday.me/bug/20191122/2057388.html