<p>Haskell and some other functional languages have Monad and Monoid types (and Semigroup, Functor, Applicative, and many others), and lists, trees, Maybe, and other types subtype all or some of these. You can write other functions that work with <em>any</em> Monad or Monoid type:</p>
<pre class="lang-haskell prettyprint-override"><code>f :: (Monad m) =&gt; m Int -&gt; m String
f x = x &gt;&gt;= \y -&gt; return (show y)
</code></pre>
<p>For example, <code>f</code> here could be given a list of ints, a tree of ints, or a Maybe of int, and would give back a list/tree/Maybe of strings. That's a trivial case, but it works for bigger/more complex processing functions as well.  This is really convenient for defining very general transformations!</p>
<p>I've seen that <strong>in Java you <em>can</em> define a common Monoid supertype</strong> with the weird-looking incantation <code>interface Monoid&lt;T extends Monoid&lt;T&gt;&gt; { T combine(T o); }</code> and then define methods that work with any Monoid, but that <strong>it <em>isn't</em> possible to do the same for Monad or Functor</strong>. Why is that? Why can you do it for <em>one</em> of them, and not both or neither?</p>
<p>Is it something about the type system, something to do with object orientation generally, or another design choice of the language? What would a Java-like language need to have in it to let all of those types work?</p>

<types><haskell><monads><java>
Why can you implement a Monoid type in Java or C#, but not Monad or Functor?
CC BY-SA 4.0
2023-08-22T23:58:10.293Z
Note that [the same is true in Swift](https://swiftfiddle.com/a4gx46lwejcnjpdnab52t24cj4), despite that having "protocols" (traits) and structs rather than being OO. (You can do OO in Swift but only for Objective-C interop; it's not idiomatic.)
Bbrk24
CC BY-SA 4.0
2023-09-06T21:26:39.567Z
This is a duplicate of https://stackoverflow.com/questions/35951818/why-can-the-monad-interface-not-be-declared-in-java/35959910#35959910
Eric Lippert
CC BY-SA 4.0
2023-11-21T16:24:56.930Z
Very technically, we can't define a type(class) of monoids in Java or Haskell because there's no support for algebraic laws; we can define a type(class) of [unital magmas](https://en.wikipedia.org/wiki/Magma_(algebra)), binary operations with units, but we can't restrict implementations to those which fulfill the monoid laws.
Corbin
<p>You need higher-kinded types. A way to introduce a generic parameter, which is itself generic.</p>
<p>Translating your Haskell example to Java-ish syntax, it might look something like this:</p>
<pre><code>public M&lt;String&gt; f&lt;M extends Monad&lt;M&gt;&gt;(M&lt;int&gt; x) {
  x.bind( (y) -&gt; M.return(y.toString()) )
}
</code></pre>
<p>Note how the <code>M</code> parameter has its own type parameter, so that I can write <code>M&lt;int&gt;</code> and <code>M&lt;String&gt;</code>.</p>

CC BY-SA 4.0
2023-08-23T00:15:11.423Z
2023-08-23T00:15:11.423Z
Fyodor Soikin
CC BY-SA 4.0
2023-08-23T12:08:56.343Z
I am not sure you _always_ need HKT itself. Rust has GAT instead (Generic Associated Type) and there are Rust implementations of Monads -- though not as nifty as Haskell's, possibly.
Matthieu M.
CC BY-SA 4.0
2023-08-23T14:52:29.240Z
The `M extends Monad<M>` trick is sometimes known as the [curiously recurring template pattern](https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern), and as the Wikipedia article notes, it’s a form of $F$-bounded quantification. It might be nice to at least mention these things in your answer.
Alexis King
CC BY-SA 4.0
2023-08-23T16:42:12.043Z
That's not what the question was about, why would I overcomplicate the answer by mentioning it? That would only make it more confusing and less accessible.
Fyodor Soikin
CC BY-SA 4.0
2023-08-24T00:01:16.980Z
I had to google [F-bounded quanification](https://stackoverflow.com/questions/59813323/advantages-of-f-bounded-polymorphism-over-typeclass-for-return-current-type-prob) there
Bruce Adams
CC BY-SA 4.0
2023-08-26T02:32:13.867Z
Rust's GATs *are* HKTs, in a limited, verbose form. Depending on which Rust designers are writing about them, GATs may be characterized as an incremental step on Rust's path towards full HKTs or as a compromise meant to prevent Rust from getting full HKTs and becoming one of *those* languages.
user570286
CC BY-SA 4.0
2023-08-30T11:37:08.040Z
@user570286 I love HKTs as much as the next functional programmer, but if it's going to increase the already painfully long compile times for Rust programs...
Jared Smith
# Why can you implement a Monoid type in Java or C#, but not Monad or Functor?
Posted by: username_0 on 2023-08-22
Haskell and some other functional languages have Monad and Monoid types (and Semigroup, Functor, Applicative, and many others), and lists, trees, Maybe, and other types subtype all or some of these. You can write other functions that work with any Monad or Monoid type:
f :: (Monad m) => m Int -> m String
f x = x >>= \y -> return (show y)

For example, f here could be given a list of ints, a tree of ints, or a Maybe of int, and would give back a list/tree/Maybe of strings. That's a trivial case, but it works for bigger/more complex processing functions as well.  This is really convenient for defining very general transformations!
I've seen that in Java you can define a common Monoid supertype with the weird-looking incantation interface Monoid> { T combine(T o); } and then define methods that work with any Monoid, but that it isn't possible to do the same for Monad or Functor. Why is that? Why can you do it for one of them, and not both or neither?
Is it something about the type system, something to do with object orientation generally, or another design choice of the language? What would a Java-like language need to have in it to let all of those types work?
**Tags:** types haskell monads java
> **Comments:**
> **username_1**: Note that [the same is true in Swift](https://swiftfiddle.com/a4gx46lwejcnjpdnab52t24cj4), despite that having "protocols" (traits) and structs rather than being OO. (You can do OO in Swift but only for Objective-C interop; it's not idiomatic.)  
> **username_2**: This is a duplicate of https://stackoverflow.com/questions/35951818/why-can-the-monad-interface-not-be-declared-in-java/35959910#35959910  
> **username_3**: Very technically, we can't define a type(class) of monoids in Java or Haskell because there's no support for algebraic laws; we can define a type(class) of [unital magmas](https://en.wikipedia.org/wiki/Magma_(algebra)), binary operations with units, but we can't restrict implementations to those which fulfill the monoid laws.  
---
## 1 answers
### Answer by username_4 on 2023-08-23. Score: 13
You need higher-kinded types. A way to introduce a generic parameter, which is itself generic.
Translating your Haskell example to Java-ish syntax, it might look something like this:
public M f>(M x) {
  x.bind( (y) -> M.return(y.toString()) )
}

Note how the M parameter has its own type parameter, so that I can write M and M.
> **Comments:**
> **username_5** (2023-08-23): I am not sure you _always_ need HKT itself. Rust has GAT instead (Generic Associated Type) and there are Rust implementations of Monads -- though not as nifty as Haskell's, possibly.  
> **username_6** (2023-08-23): The `M extends Monad<M>` trick is sometimes known as the [curiously recurring template pattern](https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern), and as the Wikipedia article notes, it’s a form of $F$-bounded quantification. It might be nice to at least mention these things in your answer.  
> **username_4** (2023-08-23): That's not what the question was about, why would I overcomplicate the answer by mentioning it? That would only make it more confusing and less accessible.  
> **username_7** (2023-08-24): I had to google [F-bounded quanification](https://stackoverflow.com/questions/59813323/advantages-of-f-bounded-polymorphism-over-typeclass-for-return-current-type-prob) there  
> **username_8** (2023-08-26): Rust's GATs *are* HKTs, in a limited, verbose form. Depending on which Rust designers are writing about them, GATs may be characterized as an incremental step on Rust's path towards full HKTs or as a compromise meant to prevent Rust from getting full HKTs and becoming one of *those* languages.  
> **username_9** (2023-08-30): @user570286 I love HKTs as much as the next functional programmer, but if it's going to increase the already painfully long compile times for Rust programs...  
---
