views:

199

answers:

3

Is every method on a class which returs this a monad?

+2  A: 

I have limited understanding of monads. I can't tell if that meets the formal definition of a monad (I don't think so, but I don't know for sure), but return this; alone doesn't allow any of the cool things monads allow (fluid interfaces are nice, but not monads imho and nowhere as useful as even simple monads like the option type monad).

This snippet from wikipedia seems to say "no":

Formally, a monad is constructed by defining two operations (bind and return) and a type constructor M [... further restrictions we don't need here]

Edit: Moreover, a monad is a type and not an operation (e.g. method) - the question should rather read "Is a class a monad if all of its methods return this?"</nitpick >

delnan
That's the definition of an implementation of monads. The categorical definition is that it's basically an endofunctor with two natural transformations. It's probably worth looking at http://en.wikipedia.org/wiki/Monad_(category_theory) rather than the programming languages version, which seems very Haskell-specific.
Gian
It's certainly worth looking at, but I hardly grasp the implementation of actual monads in Haskell, much less the theory behind it - someone smarter should do that and enlighten us, please :)
delnan
I don't agree with this answer, but I'm upvoting because I think the downvotes are unfair. It's not a bad answer with respect to the sketchiness of the question.
Gian
+5  A: 

I'm going to say a very cautious "possibly". A lot of this is contingent on your definitions.

It's worth noting that I'm taking the definition of monad from the category theory construct, not the functional programming construct.

If you think of a method A of class C that maps a C instance to another C instance (i.e. it returns this), then this would appear that C.A() is a functor from the category consisting of C instantiations to itself. Therefore it's an endofunctor, at least. It would appear that this construction obeys the basic identity and associativity properties that we expect, but further inspection would be required to say for sure.

Anyway, I wouldn't stake my life on it, and I'm not certain this is a very helpful way about thinking of such constructions, but it does seem a reasonable assumption on first inspection, at least.

Gian
I guess the original question was probably referring to monads from functional programming, this being a programming website, but I found this an interesting answer anyway. If the method modified the global state, which OOP languages generally allow, then I suppose you couldn't treat the instances of C as a category any more and this wouldn't work...
minimalis
... I should point out that I haven't studied category theory, and the above may be rubbish (but I would like to)
minimalis
The definition of monads in something like Haskell follows from the definition in category theory, so talking about one is basically talking about the other (with respect to a few corner cases). I chose to use the categorical definition precisely because some OOP language without explicit syntax for monads is never going to fit the definition provided by a language with explicit syntax. If your methods are modifying global state, then yes, the definition might get a bit dicey, but a minority of true OOP languages actually allow that (rather than imperative languages with objects bolted on).
Gian
Isn't it generally the case that objects are, by definition, global state? Which OOP languages don't consider objects to be global state (Clojure, maybe)?
Gabe
I've never seen that conception of objects presented before. An object usually forms the bounds of a local scope, and the concept of a global scope (i.e. one shared and accessible to all objects) goes away. Think Java. You can't write very much legal code that is outside of a class.
Gian
What about objects that do IO, then, or objects with mutable static members? That was the sort of thing I had in mind when I said 'global state'.
minimalis
I guess you would need to design IO functions that accumulate IO representations inside the object for later evaluation. It's true that mutable static members would probably do some interesting things to the formalism, but there are plenty of idiomatic OOP ways of avoiding using those anyway.
Gian
Ok, so you can get around it, but you'd need to add restrictions that weren't present in the original question (no IO, no mutable static members for a start).
minimalis
I'm not sure mutable static members are actually much of a problem. I just would be unwilling to commit to saying that it is definitely the case. IO doesn't seem a huge restriction. Mutation of objects (and inspecting the state afterwards) is really not very different to how the IO monad works in Haskell, for example. My original answer also hastened to caution that a lot of this was contingent on the definitions you chose :) Also, the _methods_ are the endofunctors, not the objects themselves, so you can still make a general statement about some methods within a class, just not all methods
Gian
+1  A: 

In my opinion, No.

There are at least two issues I see with it.

  1. A monad is often a glue between two functions. In this case methodA returns a type on which the next methodB is invoked, (and of course methodA and methodB both belonging to the same type).
  2. A monad is supposed to allow type transformations. So if functionA returns TypeX and functionB expects TypeY, the monad needs to provide a bind operation which can convert a Monad(TypeX) into a Monad(TypeY). The monad then goes on to take the return value of the first function, wrap it as a Monad(TypeX), transform it to Monad(TypeY) from which TypeY would get extracted and fed into functionB.

A method which returns this is actually an implementation of Fluent Interface. And while many have argued it to be a monadic as well, I would only say that while it helps resolve problems similar to what monads could otherwise solve, and while the solution would seem similar to how a monadic solution might work (instead of the "." operator, the bind method of the monad has to be invoked without any explicit do block), it is not a monad. In other words it may walk like a monad and talk like a monad, but it is not a monad.

Slight Correction to point 2: The monad needs to provide mechanisms to a) convert TypeX into Monad(TypeX), transform from Monad(TypeX) to Monad(TypeY) and a coercion from Monad(TypeY) to TypeY

Dhananjay Nene
1: By method chaining, this is trivially doable, e.g. `C.X().Y().Z()`, type enforcement requires that they have the same domain and range types. 2: That's a type system enforcement issue, but this is trivially representable in most languages that have a notion of `object`, because they also have notions such as interfaces or abstract classes. As for your third paragraph, I'm not sure I saw in there a condition that excludes the kind of definition the OP was asking about. You kinda hand-waved your way from "this looks like something else" to "therefore it's not a monad".
Gian
A monad adds value between the return value of one function and the invocation of the next and also performs the necessary bind. In this case the output of one method is directly fed to the next, and being an OO language the bind is simply built into the "." operator provided by the language. Moreover there is no possibility of the return type of one function being transformed by the monad into a different type. So I am saying I cannot see the value addition or role being played by monads in this context.Monads perform value addition in a pipeline. In this case I only see the pipeline.
Dhananjay Nene
I certainly agree that the things you can reasonably call "monads" (or monad-shaped) in this setting are probably not very _interesting_ monads, but it seems to me that the basic shape is still precisely the same. The natural transformations seem to be readily captured by single inheritance and down-casting. Some OO languages will happily perform these as implicit coercions, so there _is_ a possibility of the return type of one function being transformed into a different type.
Gian