Functional programming 流是否在Java8Monad中?
这似乎是一个好消息 溪流也是单子吗Functional programming 流是否在Java8Monad中?,functional-programming,java-8,monads,java-stream,Functional Programming,Java 8,Monads,Java Stream,这似乎是一个好消息 溪流也是单子吗 有人能识别可选单子中的内函子和两个自然变换吗?编辑下面的答案是不正确的(保留在这里作为历史记录) 是的,在每种情况下,函子都由类及其map方法组成,两种自然转换是of和flatMap(identity) 正确的答案似乎是。如果你知道Haskell:Java的流不是别的,那么Haskell的列表monad[]和Java的可选项不是别的,Haskell的可能是monad。是的,Java.util.Stream.Stream满足monad定律 以下先决条件是: St
有人能识别可选单子中的内函子和两个自然变换吗?编辑下面的答案是不正确的(保留在这里作为历史记录) 是的,在每种情况下,函子都由类及其
map
方法组成,两种自然转换是of
和flatMap(identity)
正确的答案似乎是。如果你知道Haskell:Java的流不是别的,那么Haskell的列表monad[]和Java的可选项不是别的,Haskell的可能是monad。是的,
Java.util.Stream.Stream
满足monad定律
以下先决条件是:
Stream
应该是Functor,即提供以下函数fmap::(a->b)->ma->mb
。
如果我们查看源代码,就会发现它已经有函数流映射(函数映射器)
unit
(也称为return
)操作:unit::a->ma
。这一点很明显:流(T)
bind
或
操作:
bind::MA->(a->MB)->MB
:流平面图(函数映射器)
join::M(ma)->ma
:这一个在流中不存在,但我们可以从bind
中推断出来
(返回a)绑定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
函数f=str->str.chars().boxed();
字符串a=“abc”;
流左=流(a).flatMap(f);
右流=f.apply(a);
//左边应该和右边一样
右标识:m绑定单位m
Stream=Stream.of(“abc”、“def”);
Stream left=Stream.flatMap(str->Stream.of(str));
//左侧应与“abc”、“def”流相同
关联性:(m bind f)bind g m bind(\x->f x bind g)
函数f=integer->Arrays.stream(integer.toHexString(integer.split)(“”);
函数g=string->Stream.of(string.map)(str->newbiginger(str,16));
流mLeft=流of(4778961453);
左流=mLeft.flatMap(f).flatMap(g);
溪流mRight=溪流of(4778961453);
Stream right=mRight.flatMap(整数->f.apply(整数).flatMap(g));
//左边应该和右边一样
看来溪流真的是单子!但是要小心,同样的情况也可能发生在
可选的上,它有时会违反一元法则。我有一种直觉,如果您使用parallel()
,在某些情况下可能会违反它,因为它可以更改执行顺序。如果您知道可能发生的情况,请在下面进行评论。我想您对Streams不太了解。然而,这又有什么关系呢?在Java中不能抽象类型构造函数,也不能重载返回类型,因此可能无法编写monad构造函数中多态的Java代码。值得注意的是,Optional在处理null值时违反了左标识定律,因此从技术上讲不是monadOptional.ofNullable(null).flatMap(Optional::of)
生成一个空的Optional,而Optional.of(null)
抛出一个NPE。当然,它仍然提供了monad的大部分好处。我们需要定义:\displaystyle\begin{array}{lcl}\mathit{return}&:&a\rightarrow\mathit{Stream},a\\\ mathit{join}&:&\mathit{Stream},(\mathit{Stream},a)\rightarrow\mathit{Stream},a\end{array}链接很好,但要想知道答案是“是”还是“否”,并没有简单的方法。请考虑更新你的问题,这样人们就可以很快地看到答案是什么。@ TITROM我想删除我的答案,因为它是错误的,但是不会让我。@ N.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")
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