10

Forgive me if this question seems stupid, but I'm quite new to the whole world of functional programming so I'll need some denizens on StackOverflow to set me straight.

From what I gather, an operation on a monad returns a monad. Does this mean that monads have a fluent interface, whereby each function that is applied on a monad returns that monad after it applies some operation to the variable it wraps?

  • 2
    I don't think this is a meaningful question—a fluent interface is, I think, enough of an OO concept that comparing it to a monad (at least in Haskell, where monads are a "type class", something very different from an OO class) isn't particularly useful. (But I could be wrong.) – Antal Spector-Zabusky Mar 25 '11 at 21:38
  • Yeah I wasn't sure how to ask this question, since I've always been an OO programmer. Sorry if I'm making no sense. –  Mar 25 '11 at 21:42
  • The question makes *sense*, but I'm not sure it has a good *answer*. But I haven't done enough OO programming to give you a useful answer. – Antal Spector-Zabusky Mar 25 '11 at 22:09
  • @AntalSpector-Zabusky If you extend the monad concept to OOP, it makes sense. In particular, concepts like Promises are very "monadic", and [some people](https://importantshock.wordpress.com/2009/01/18/jquery-is-a-monad/) have used the JQuery wrapper as an example of a monad. Generally these also have fluent interfaces. – Garrett Motzner Apr 29 '20 at 17:18

2 Answers2

8

Presumably you're referring to the bind operator associated with monads, wherein one can start with a monadic value, bind it to a monadic function, and wind up with another monadic value. That's a lot like a "fluent method" (or a set of such making up a "fluent interface") that returns a "this" pointer or reference, yes, but what you'd be missing out on there is that the monadic function need not return a monadic value that's the same type as the input value. The fluent method convention is to return the same type of value so as to continue chaining calls that are all valid on the instance (or instances) being prepared.

The monadic bind operator signature looks more like this:

M[a] -> (a -> M[b]) -> M[b]

That is, the "return value" is possibly of a type different from to the first input value's type. It's only the same when the provided function has the type

(a -> M[a])

It all depends on the type of the monadic function—and, more specifically, the return type of the monadic function.

If you were to constrain the domain of the monadic functions you'd accept to those that return the same type as the monadic value supplied to the bind operator, then yes, you'd have something that behaves like a fluent interface.

seh
  • 14,999
  • 2
  • 48
  • 58
  • While you've cleared up how monads behave exactly, it looks like I still need to do more research! Thanks and accepted. –  Mar 26 '11 at 04:31
1

Based on what I know about fluent interfaces, they are mostly about making the code "read nicely" by using method chaining. So for example:

Date date = date()
    .withYear(2008)
    .withMonth(Calendar.JANUARY)
    .withDayOfMonth(15)
    .toDate();

A Haskell do-notation version of it (using an imaginary date api) could look like:

do date
   withYear 2008
   withMonth JANUARY
   withDayOfMonth 15
   toDate

Whether or not this or other do-notation based DSLs like it qualify as a "fluent interface" is probably up for discussion, since there is no formal definition of what a "fluent interface" is. I'd say if it reads like this then it's close enough.

Note that this isn't exactly specific to monads; monads CAN have a fluent interface if you don't require method calling, but that would depend on the function names and the way the API is used.

Dobes Vandermeer
  • 8,463
  • 5
  • 43
  • 46