Monads with Java 8

In the interest of helping to understand what a monad is, can anyone provide an example using java? Are they possible?

Lambda expressions are possible using java if you download the ldbd-compatible JDK8 with a preliminary release here http://jdk8.java.net/lambda/

An example lambda using this JDK is shown below, can anyone provide a relatively simple 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); } 
+74
java java-8 monads optional
Nov 19 '12 at 12:58
source share
8 answers

Just FYI:

The proposed JDK8 Optional class satisfies three demonstrates that.

All that is required is Monad to provide two functions that comply with the laws of three .

Two functions:

  • Put value in monadic context

    • Haskell Possibly: return / Just
    • Scala Option: Some
    • Functional Java variant: Option.some
    • JDK8 Extras: Optional.of
  • Apply function in monadic context

    • Haskell Possibly: >>= (aka bind )
    • Scala Option: flatMap
    • Functional Java option: flatMap
    • JDK8 Optional: flatMap

Please see gist above for a demonstration of the java three laws.

NOTE. One of the key things to understand is the function signature for use in a monadic context: it takes the type of the raw value and returns the monadic type.

In other words, if you have an Optional<Integer> instance, the functions you can pass to the flatMap method will have the signature (Integer) -> Optional<U> , where U is the type of the value, which should not be Integer , for example 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)); 

You do not need any Monad interface to encode this method or to think so. In Scala, you do not code the Monad interface (unless you use the Scalaz library ...). It seems that JDK8 will provide Java users with the ability to use this style of chained monadic computing.

Hope this will be helpful!

Update . here .

+75
Nov 12 '13 at 14:55
source share

Java 8 will have lambdas; monads are a completely different story. They are difficult to explain in functional programming (as evidenced by the large number of textbooks on this subject in Haskell and Scala).

Monads are a typical feature of statically typed functional languages. To describe them in OO-talk, you could introduce the Monad interface. Classes that implement Monad will then be called "monadic," provided that when implementing Monad implementation obeys what is known as the "laws of the monad." The language then provides some syntactic sugar, which makes working with instances of the Monad class interesting.

Now Iterable in Java has nothing to do with monads, but as an example of the type that the Java compiler specifically considers (the foreach syntax that ships with Java 5), ​​consider the following:

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

So, although we could use the Iterable Iterator ( hasNext and company) methods in the old for style, Java provides us with this syntactic sugar as a special case.

Just as classes implementing Iterable and Iterator must obey Iterator laws (Example: hasNext should return false if there is no next element), which would be useful in the foreach syntax, there would be several monadic classes that would be useful with the corresponding do ( as it is called in Haskell) or the Scala for notation.

So -

  • What are some good examples of monadic classes?
  • What will be the syntactic sugar for working with them?

In Java 8, I don’t know - I know about lambda notation, but I don’t know any other special syntactic sugar, so I have to give you an example in another language.

Monads often serve as container classes (examples are examples). Java already has java.util.List , which is clearly not monadic, but here is Scala s:

 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) st 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") 

What is (roughly) syntactic sugar for:

 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 // 

Here's a Scala feature that uses monads to provide an understanding of lists.

So, a List in Scala is a monad, because it obeys the laws of the Scala monad, which stipulate that all monad implementations must have the appropriate flatMap , map and filter methods (if you are interested in the laws, there is a better description in the Monads are Elephants blog which I have found so far). And, as you can see, lambdas (and HoF) are absolutely necessary, but not sufficient for the practical use of these kinds of things.

There are tons of useful monads, besides container ships. They have all kinds of applications. My favorite should be the Option monad in Scala ( Maybe monad in Haskell), which is a type of wrapper that leads to zero security: the Scala API page for the Option monad has a very simple usage example: http://www.scala-lang.org /api/current/scala/Option.html In Haskell, monads are useful for representing IO, as a way around the fact that non-monodonic Haskell code has an undefined execution order.

Having a lambda is the first small step into the world of functional programming; monads require both a monad agreement and a sufficiently large set of monadic types used, as well as syntactic sugar, to make working with them fun and useful.

Since Scala is perhaps the closest language to Java that also allows (monadic) functional programming, take a look at this Monad tutorial for Scala if you are interested (still): http: //james-iry.blogspot .jp / 2007/09 / monads-are-elephants-part-1.html

A quick googling shows that there is at least one attempt to do this in Java: https://github.com/RichardWarburton/Monads-in-Java -

Unfortunately, the explanation of monads in Java (even with lambdas) is just as difficult to explain full-blown object-oriented programming in ANSI C (instead of C ++ or Java).

+55
Nov 19 '12 at 14:15
source share

Despite the fact that monads can be implemented in Java, any calculations associated with them are doomed to become a dirty combination of generics and curly braces.

I would say that Java is definitely not a language to use to illustrate their work or to study their meaning and essence. To do this, it is much better to use JavaScript or pay an additional price and learn Haskell.

In any case, I warn you that I just implemented the monad monad using the new Java 8 lambdas . This is definitely a pet project, but it works in a non-trivial test case.

You can find it on my blog , but I will tell you a few details.

The state monad is basically a function from state to pair (state, content) . Usually you provide the state with general type S and content with general type A.

Since Java does not have pairs, we must model them using a certain class, let us call it Scp (state-content pair), which in this case will have the general type Scp<S,A> and the constructor new Scp<S,A>(S state,A content) . After that, we can say that the monadic function will be of type

 java.util.function.Function<S,Scp<S,A>> 

which is @FunctionalInterface . This means that its one and only implementation method can be called without naming it, passing a lambda expression with the correct type.

The StateMonad<S,A> class is mainly a wrapper around a function. Its constructor can be called, for example. from

 new StateMonad<Integer, String>(n -> new Scp<Integer, String>(n + 1, "value")); 

The state monad stores the function as an instance variable. Then you need to provide a public method of access to it and pass it to the state. I decided to call it s2scp ("state to state-content pair").

To complete the definition of the monad, you must provide the unit (aka return) and the bind method (aka flatMap). Personally, I prefer to specify the unit as static, and bind is an instance member.

In the case of a state monad, the unit shall be as follows:

 public static <S, A> StateMonad<S, A> unit(A a) { return new StateMonad<S, A>((S s) -> new Scp<S, A>(s, a)); } 

while bind (as an instance member):

 public <B> StateMonad<S, B> bind(final Function<A, StateMonad<S, B>> famb) { return new StateMonad<S, B>((S s) -> { Scp<S, A> currentPair = this.s2scp(s); return famb(currentPair.content).s2scp(currentPair.state); }); } 

You have noticed that bind must introduce a generic type B, because it is a mechanism that allows you to bind heterogeneous state monads and gives this and any other monad a wonderful opportunity to move computations from type to type.

I would dwell on Java code here. The complex material is in the GitHub project. Compared to previous versions of Java, lambdas removes many curly braces, but the syntax is still quite confusing.

Just as an aside, I show how a similar state monad code can be written in other major languages. In the case of Scala, bind (which in this case should be called flatMap) reads like

 def flatMap[A, B](famb: A => State[S, B]) = new State[S, B]((s: S) => { val (ss: S, aa: A) = this.s2scp(s) famb(aa).s2scp(ss) }) 

whereas JavaScript bindings are my favorite; 100% functional, meager and average, but, of course, impersonal:

 var bind = function(famb){ return state(function(s) { var a = this(s); return famb(a.value)(a.state); }); }; 

<shameless> I cut a few corners here, but if you are interested in the details, you will find them on my WP blog. </shameless>

+9
Apr 27 '14 at 7:33
source share

The only way to understand monads is to write several libraries of combinators, notice the resulting duplication, and then discover for yourself that the monads can eliminate this duplication. Opening this, everyone builds some intuition for what a monad is ... but this intuition is not a thing that you can communicate with someone else directly - it seems that everyone should undergo the same experience of generalizing to monads from some specific examples of a library of combinators. However

Here I found some materials to learn Mondas.

Hope to be of service to you too.

codecommit

James-iry.blogspot

debasishg.blogspot

+5
Nov 19 '12 at 13:20
source share

Here about monads that are hard to understand: monads are a pattern, not a specific type. Monads are a form; they are an abstract interface (not in the sense of Java) more than concrete data composition. As a result, any example-based guidance is doomed to incompleteness and failure. [...] The only way to understand monads is to see them for them: a mathematical construction.

Monads are not metaphors Daniel Spiewak




Monads in Java SE 8

Monad List

 interface Person { List<Person> parents(); default List<Person> greatGrandParents1() { List<Person> list = new ArrayList<>(); for (Person p : parents()) { for (Person gp : p.parents()) { for (Person ggp : p.parents()) { list.add(ggp); } } } return list; } // <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper) default List<Person> greatGrandParents2() { return Stream.of(parents()) .flatMap(p -> Stream.of(p.parents())) .flatMap(gp -> Stream.of(gp.parents())) .collect(toList()); } } 

Perhaps the monad

 interface Person { String firstName(); String middleName(); String lastName(); default String fullName1() { String fName = firstName(); if (fName != null) { String mName = middleName(); if (mName != null) { String lName = lastName(); if (lName != null) { return fName + " " + mName + " " + lName; } } } return null; } // <U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) default Optional<String> fullName2() { return Optional.ofNullable(firstName()) .flatMap(fName -> Optional.ofNullable(middleName()) .flatMap(mName -> Optional.ofNullable(lastName()) .flatMap(lName -> Optional.of(fName + " " + mName + " " + lName)))); } } 



Monad is a generic template for encapsulating a nested control flow. That is, a way to create reusable components from nested imperative idioms.

It is important to understand that a monad is not just a general wrapper class with a flat map. For example, an ArrayList with the flatMap method flatMap not be a monad. Because monad laws prohibit side effects.

Monk is formalism. It describes the structure, regardless of content or meaning. People struggle with meaningless (abstract) things. Therefore, they come up with metaphors that are not monads.

See also: conversation between Eric Majer and Gilad Brah.

+4
Jan 08 '16 at 1:28
source share

This blog post gives a step-by-step example of how you can implement the Monad type (interface) in Java and then use it to define Maybe as a practical application.

This post explains that one monad is built into the Java language, emphasizing that monads are more common than many programmers might think, and that coders often inadvertently invent them .

+2
Dec 18
source share

I like to think about monads in slighlty in a more mathematical (but still informal) fashion. After that, I will explain the relationship to one of the Java 8 CompletableFuture mosaics.

First of all, the monad M is a functor. That is, it converts the type to another type: if X is a type (e.g. String ), we have a different type M<X> (e.g. List<String> ). Moreover, if we have the types of transformations / functions X -> Y , we must get the function M<X> -> M<Y> .

But there is more data for such a monad. We have a so-called unit, which is a function X -> M<X> for each type of X In other words, each object X can be naturally wrapped in a monad.

The most characteristic data of the monad, however, is its product: the function M<M<X>> -> M<X> for each type X

All these data should satisfy certain axioms, such as functoriality, associativity, single laws, but I will not go into details here, and this also does not matter for practical use.

Now we can derive another operation for monads, which is often used as an equivalent definition for monads, a binding operation: the value / object in M<X> can be associated with the function X -> M<Y> to get a different value in M<Y> . How do we achieve this? Well, first apply functoriality to the function to get the function M<X> -> M<M<Y>> . Then we apply the monadic product to the target to obtain the function M<X> -> M<Y> . Now we can connect the value of M<X> to get the value in M<Y> as desired. This binding operation is used to combine several monodic operations.

Now let's move on to the CompletableFuture example, i.e. CompletableFuture = M Think of the CompletableFuture<MyData> object as some kind of computation that runs asynchronously and that will result in some future MyData object. What are the monadic operations here?

  • Functionality
  • implemented using the thenApply method: the calculation is performed first, and as soon as the result is available, the function provided by thenApply is used to convert the result to another type
  • the monadic block is implemented using the completedFuture method: as the documentation reports, the final calculation is already completed and immediately gives the specified value.
  • the monadic product is not implemented by the function, but the binding operation below is equivalent to it (along with functoriality), and its semantic meaning is as follows: when calculating type CompletableFuture<CompletableFuture<MyData>> , the calculation asynchronously gives another calculation in CompletableFuture<MyData> , which in turn gives some value to MyData later, so doing both calculations after the other gives one calculation as a whole
  • the resulting binding operation is implemented by the thenCompose method

As you can see, calculations can now be wrapped in a special context, namely asynchrony. Common monadic structures allow us to relate such computations in this context. CompletableFuture , for example, is used in the Lagom framework to easily create highly asynchronous request handlers that are transparently backed up by efficient thread pools (instead of processing each request with a dedicated thread).

0
Jul 07 '17 at 18:41
source share

Despite all the controversy over whether Optional satisfies the laws of the Monad or not, I usually like to look at Stream , Optional and CompletableFuture same way. In truth, they all provide flatMap() and that’s all I care about, and let me take the “delicious side effect composition” (quoted by Eric Meyer). Thus, we can have the corresponding Stream , Optional and CompletableFuture as follows:

57518402-d4e59f00-7310-11e9-8ae0-f41a91aafd64.png

As for monads, I usually flatMap() thinking only about flatMap() (from Eric Meyer's Principles of Reactive Programming):

Eric-Meijer-flatMap

0
May 10 '19 at 9:55
source share



All Articles