答案 0 :(得分:11)
答案 1 :(得分:2)
如果您了解Haskell:Java的流不是别的,那么Haskell的列表monad []和Java的Optional就是Haskell的Maybe monad。
答案 2 :(得分:2)
是的,java.util.stream.Stream
符合Monad法律。
满足以下先决条件:
Stream
应该是 Functor ,即提供以下功能fmap :: (a -> b) -> M a -> M b
。
如果我们查看源代码,将会看到它已经具有功能Stream<R> map(Function<T, R> mapper)
它应具有unit
(又称return
)操作:unit :: a -> M a
。显而易见:Stream<T> of(T t)
。
它应该具有bind
或 join
操作:
bind :: M a -> (a -> M b) -> M b
:Stream<R> flatMap(Function<T, Stream<R>> mapper)
join :: M (M a) -> M a
:Stream
中没有这个,但是我们可以从bind
推断出来。现在我们具有必需的功能。但这还不够吗?我们需要证明单子法则是有效的。让我们看看它们:
左身份: (return a) bind f <=> f a
Function<String, Stream<Integer>> f = str -> str.chars().boxed();
String a = "abc";
Stream<Integer> left = Stream.of(a).flatMap(f);
Stream<Integer> right = f.apply(a);
//left should be same as right
右身份: m bind unit <=> m
Stream<String> stream = Stream.of("abc", "def");
Stream<String> left = stream.flatMap(str -> Stream.of(str));
// left should be same as Stream.of("abc", "def")
关联性: (m bind f) bind g <=> m bind (\x -> f x bind g)
Function<Integer, Stream<String>> f = integer -> Arrays.stream(Integer.toHexString(integer).split(""));
Function<String, Stream<BigInteger>> g = string -> Stream.of(string).map(str -> new BigInteger(str, 16));
Stream<Integer> mLeft = Stream.of(47789, 61453);
Stream<BigInteger> left = mLeft.flatMap(f).flatMap(g);
Stream<Integer> mRight = Stream.of(47789, 61453);
Stream<BigInteger> right = mRight.flatMap(integer -> f.apply(integer).flatMap(g));
//left should be same as right
因此,看起来Streams确实是monads!但是请注意,Optional
可能会发生同样的情况,有时会违反摩纳哥法律。如果您知道可能发生的情况,请在下面评论。