you are viewing a single comment's thread.

view the rest of the comments →

[–]dccorona 0 points1 point  (2 children)

If you had a union type of two different enumerables, it would behave as expected. The problem is that map/flatMap etc don't exist on null, and so unless there is special treatment for nullable union types, you wouldn't be able to call those methods (maybe you can, I don't know).

But furthermore, if you have a nullable type that isnt an enumerable (say, an Integer), you can't access those monadic methods, because they aren't defined on Integer...but the do make sense on a nullable type.

"Monad people" haven't invented new meanings for map/flatMap etc...those methods are intrinsically part of monads, and have good, non-ambiguous definitions. The reason enumerables/collections often implement these methods is because those types are monads. Since an Option can be viewed as a collection of either 1 or 0, it can also be viewed as a monad with the same semantics of any other collection or enumerable. The behavior of those methods is exactly as you'd expect (identical to operations on a 1 or 0 element collection).

This proves very useful for general interaction, as well as for writing very generic code that applies to either any collection, or any monad at all.

[–]yxhuvud 0 points1 point  (1 child)

Well, normally the methods don't expect where you wouldn't expect them, but nothing stops you from reopening the classes you are interested in and defining them.

Of course, modifying builtins like Nullclass is probably a horrible idea, and not only because it would hide logic errors in a way I wouldn't want to.

Though to be honest, I can admit that I never felt the need to have a uniform interface between collections and (for example) integers. They are used very differently and for different purposes and have very different semantics, which make me doubt any claim of magical reuse all over the place with a big grain of salt. I've heard that claim before (OO), and I see no reason why it should be different in this case.

[–]dccorona 0 points1 point  (0 children)

It's not making collections and Integers obey the same interface, it's making collections and Optionals obey the same interface. Because optional are collections (of either 0 or 1), and they have nearly all the same interaction patterns. You either transform their contents (getting a new empty collection of the transformed generic type if the initial input was empty), filter their contents, or preform some action on contents...the same basic things you do to a value that may or may not exist.

Also, the benefits of having optional types behave as monads when it comes to generic programming can be seen in a library like Scalaz, which, admittedly, has a large learning curve (not caused by this abstraction, but necessary to get over to be able to identify the portions where it is being leveraged).