Java 8 中的单子

新手上路,请多包涵

为了帮助理解什么是 monad,有人可以提供一个使用 java 的例子吗?他们可能吗?

如果您从此处 http://jdk8.java.net/lambda/ 下载预发布的 lambda 兼容 JDK8,则可以使用 java 来使用 Lambda 表达式

下面显示了使用此 JDK 的 lambda 示例,有人可以提供一个相对简单的 monad 吗?

 public interface TransformService {
        int[] transform(List<Integer> inputs);
    }
    public static void main(String ars[]) {
        TransformService transformService = (inputs) -> {
            int[] ints = new int[inputs.size()];
            int i = 0;
            for (Integer element : inputs) {
                ints[i] = element;
            }
            return ints;
        };

        List<Integer> inputs = new ArrayList<Integer>(5) {{
            add(10);
            add(10);
        }};
        int[] results = transformService.transform(inputs);
    }

原文由 NimChimpsky 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 414
2 个回答

仅供参考:

提议的 JDK8 Optional确实满足 三个 Monad 定律。这是 证明这一点的要点

Monad 所需要的只是提供符合 三个 定律的 两个 函数。

两个函数:

  1. 值放入 monadic 上下文中

    • Haskell 的可能: return / Just
    • Scala 的选项: Some
    • Java 的功能选项: Option.some
    • JDK8的可选: Optional.of
  2. 在 monadic 上下文中应用函数

    • Haskell 的可能: >>= (又名 bind
    • Scala 的选项: flatMap
    • Java 的功能选项: flatMap
    • JDK8的可选: flatMap

请参阅 上面的要点 以获得三个定律的 java 演示。

注意:要理解的关键事情之一是 在 monadic 上下文中应用的函数 的签名:它采用原始值类型,并返回 monadic 类型。

In other words, if you have an instance of Optional<Integer> , the functions you can pass to its flatMap method will have the signature (Integer) -> Optional<U> , where U 是一个值类型,它不一定是 Integer ,例如 String

 Optional<Integer> maybeInteger = Optional.of(1);

// Function that takes Integer and returns Optional<Integer>
Optional<Integer> maybePlusOne = maybeInteger.flatMap(n -> Optional.of(n + 1));

// Function that takes Integer and returns Optional<String>
Optional<String> maybeString = maybePlusOne.flatMap(n -> Optional.of(n.toString));

您不需要任何类型的 Monad 接口来以这种方式编码或以这种方式思考。在 Scala 中,您无需为 Monad 接口编写代码(除非您使用的是 Scalaz 库…)。 JDK8 似乎也将授权 Java 人员使用这种 _链式单子计算_。

希望这会有所帮助!

更新: 在这里 写博客。

原文由 ms-tg 发布,翻译遵循 CC BY-SA 3.0 许可协议

Java 8 将有 lambda;单子是一个完全不同的故事。它们很难在函数式编程中解释(Haskell 和 Scala 中有关该主题的大量教程证明了这一点)。

Monad 是静态类型函数式语言的典型特征。要用 OO 语言来描述它们,您可以想象一个 Monad 接口。实现 Monad 的类将被称为“monadic”,前提是在实现 Monad 时遵守所谓的“monad 法则”。然后,该语言提供了一些 _语法糖_,使处理 Monad 类的实例变得有趣。

现在 Iterable 在 Java 中与 monad 无关,但作为 Java 编译器特别对待的类型的示例(Java 5 附带的 foreach 语法),请考虑以下内容:

 Iterable<Something> things = getThings(..);
for (Something s: things) {  /* do something with s */ }

So while we could have used Iterable ’s Iterator methods ( hasNext and company) in an old-style for loop, Java grants我们把这个语法糖当作一个 _特例_。

So just as classes that implement Iterable and Iterator must obey the Iterator laws (Example: hasNext must return false 如果没有下一个元素)在 foreach 语法中有用 - 将存在几个 单子 类,这些类将与相应的 do 符号一起使用(在 Haskell 中称为)或 Scala 的 for 符号。

所以 -

  1. 什么是 monadic 类的好例子?
  2. 处理它们的语法糖会是什么样子?

在 Java 8 中,我不知道——我知道 lambda 符号,但我不知道其他特殊的语法糖,所以我必须用另一种语言给你一个例子。

Monad 通常用作 容器 类(列表就是一个例子)。 Java 已经有 java.util.List 这显然不是单子的,但这是 Scala 的:

 val nums = List(1, 2, 3, 4)
val strs = List("hello", "hola")
val result = for { // Iterate both lists, return a resulting list that contains
                   // pairs of (Int, String) s.t the string size is same as the num.
  n <- nums
  s <- strs if n == s.length
} yield (n, s)
// result will be List((4, "hola"))
// A list of exactly one element, the pair (4, "hola")

这是(大致)语法糖:

 val nums = List(1, 2, 3, 4)
val strs = List("hello", "hola")
val results =
nums.flatMap( n =>
  strs.filter(s => s.size == n).   // same as the 'if'
       map(s => (n, s))            // Same as the 'yield'
)
// flatMap takes a lambda as an argument, as do filter and map
//

这显示了 Scala 的一个特性,其中利用 monad 来提供 _列表理解_。

所以 Scala 中的 List 是一个 monad,因为它遵守 Scala 的 monad 法则,该法则规定所有 monad 实现必须符合 flatMap filter map --- 方法(如果您对法则感兴趣,“Monads are Elephants”博客条目是迄今为止我找到的最好的描述)。而且,正如您所看到的,lambda(和 HoF)是绝对 必要 的,但 不足以 使这种东西在实际中有用。

除了容器类的之外,还有很多有用的 monad。他们有各种各样的应用程序。我最喜欢的一定是 Scala 中的 Maybe Option (Haskell 中的 — monad),它是一种包装类型,它带来了 _空安全性_:Scala API 页面 Option monad 有一个非常简单的示例用法: http ://www.scala-lang.org/api/current/scala/Option.html 在 Haskell 中,monads 在表示 IO 时很有用,作为解决这个问题的一种方式非 monadic Haskell 代码具有不确定的执行顺序。

拥有 lambda 是进入函数式编程世界的第一步; monad 需要 monad 约定和一组足够大的可用 monadic 类型, 以及 语法糖以使使用它们变得有趣和有用。

由于 Scala 可以说是最接近 Java 的语言,它也允许(monadic)函数式编程,如果您(仍然)感兴趣,请查看这个 Scala 的 Monad 教程:http: //james-iry.blogspot.jp/2007/09/ monads-are-elephants-part-1.html

粗略的谷歌搜索显示至少有一次尝试在 Java 中执行此操作: https ://github.com/RichardWarburton/Monads-in-Java -

遗憾的是,解释 Java 中的 monad(即使使用 lambda)与解释 ANSI C(而不是 C++ 或 Java)中成熟的面向对象编程一样困难。

原文由 Faiz 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏