You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -335,6 +337,41 @@ Examples of applicative functors include:
335
337
336
338
In addition to implementing `fmap` from `Functor`, implementing an applicative functor involves providing two methods: `pure`, a method that lifts a value into the functor; and `zip`, a method that applies a lifted function to a lifted value, returning a new lifted value. As usual, there are [some laws](https://hackage.haskell.org/package/base-4.9.1.0/docs/Control-Applicative.html) that should be adhered to.
337
339
340
+
### <aname="monads">Monads</a>
341
+
342
+
Monads are applicative functors that additionally support a chaining operation, `flatMap :: (a -> f b) -> f a -> f b`: a function from the functor's parameter to a new instance of the same functor over a potentially different parameter. Because the function passed to `flatMap` can return a different instance of the same functor, functors can take advantage of multiple constructions that yield different functorial operations, like short-circuiting, as in the following example using `Either`:
343
+
344
+
```Java
345
+
classPerson {
346
+
Optional<Occupation>occupation() {
347
+
returnOptional.empty();
348
+
}
349
+
}
350
+
351
+
classOccupation {
352
+
}
353
+
354
+
publicstaticvoid main(String[] args) {
355
+
Fn1<String, Either<String, Integer>> parseId = str ->Either.trying(() ->Integer.parseInt(str), __ -> str +" is not a valid id");
356
+
357
+
Map<Integer, Person> database =newHashMap<>();
358
+
Fn1<Integer, Either<String, Person>> lookupById = id ->Either.fromOptional(Optional.ofNullable(database.get(id)),
359
+
() ->"No person found for id "+ id);
360
+
Fn1<Person, Either<String, Occupation>> getOccupation = p ->Either.fromOptional(p.occupation(), () ->"Person was unemployed");
In the previous example, if any of `parseId`, `lookupById`, or `getOccupation` fail, no further `flatMap` computations can succeed, so the result short-circuits to the first `left` value that is returned. This is completely predictable from the type signature of `Monad` and `Either`: `Either<L, R>` is a `Monad<R>`, so the single arity `flatMap` can have nothing to map in the case where there is no `R` value. With experience, it generally becomes quickly clear what the logical behavior of `flatMap`*must* be given the type signatures.
370
+
371
+
That's it. Monads are neither [elephants](http://james-iry.blogspot.com/2007/09/monads-are-elephants-part-1.html) nor are they [burritos](https://blog.plover.com/prog/burritos.html); they're simply types that support a) the ability to lift a value into them, and b) a chaining function `flatMap :: (a -> f b) -> f a -> f b` that can potentially return different instances of the same monad. If a type can do those two things (and obeys [the laws](https://wiki.haskell.org/Monad_laws)), it is a monad.
372
+
373
+
Further, if a type is a monad, it is necessarily an `Applicative`, which makes it necessarily a `Functor`, so *lambda* enforces this tautology via a hierarchical constraint.
374
+
338
375
### <aname="traversables">Traversables</a>
339
376
340
377
Traversable functors -- functors that can be "traversed from left to right" -- are implemented via the `Traversable` interface.
@@ -407,8 +444,7 @@ Examples of traversable functors include:
407
444
- `Choice*`
408
445
- `Either`
409
446
- `Const` and `Identity`
410
-
- `TraversableIterable` for wrapping `Iterable` in an instance of `Traversable`
411
-
- `TraversableOptional` for wrapping `Optional` in an instance of `Traversable`
447
+
- `LambdaIterable` for wrapping `Iterable` in an instance of `Traversable`
412
448
413
449
In addition to implementing `fmap` from `Functor`, implementing a traversable functor involves providing an implementation of `traverse`.
414
450
@@ -419,6 +455,56 @@ As always, there are [some laws](https://hackage.haskell.org/package/base-4.9.1.
419
455
420
456
Lambda also supports a few first-class [algebraic data types](https://www.wikiwand.com/en/Algebraic_data_type).
421
457
458
+
### <a name="maybe">Maybe</a>
459
+
460
+
`Maybe` is the _lambda_ analog to `java.util.Optional`.It behaves in much of the same way as `j.u.Optional`, except that it quite intentionally does not support the inherently unsafe `j.u.Optional#get`.
***Note***: One compatibility difference between `j.u.Optional` and `Maybe` is how `map`/`fmap` behave regarding functions that return `null`: `j.u.Optional` re-wraps `null` results from `map` operations in another `j.u.Optional`, whereas `Maybe` considers this to be an error, and throws an exception. The reason `Maybe` throws in this case is because `fmap` is not an operation to be called speculatively, and so any function that returns `null` in the context of an `fmap` operation is considered to be erroneous. Instead of calling `fmap` with a function that might return `null`, the function result should be wrapped in a `Maybe` and `flatMap` should be used, as illustrated in the following example:
HLists are type-safe heterogeneous lists, meaning they can store elements of different types in the same list while facilitating certain type-safe interactions.
CoProduct3<String, Integer, Character, ?> coProduct3 = coProduct2.diverge(); // still just the coProduct2 value, adapted to the coProduct3 shape
538
630
```
539
631
540
-
There are `CoProduct` and `Choice` specializations for type unions of up to 5 different types: `CoProduct2` through `CoProduct5`, and `Choice2` through `Choice5`, respectively.
632
+
There are `CoProduct` and `Choice` specializations for type unions of up to 8 different types: `CoProduct2` through `CoProduct8`, and `Choice2` through `Choice8`, respectively.
541
633
542
634
### <a name="either">Either</a>
543
635
@@ -647,4 +739,4 @@ Unfortunately, due to Java's type hierarchy and inheritance inconsistencies, thi
647
739
<a name="license">License</a>
648
740
-------
649
741
650
-
_lambda_ is part of [palatable](http://www.github.com/palatable), which is distributed under [The MIT License](http://choosealicense.com/licenses/mit/).
742
+
_lambda_ is part of [palatable](http://www.github.com/palatable), which is distributed under [The MIT License](http://choosealicense.com/licenses/mit/).
0 commit comments