
<p>A problem I sometimes run into when using a language like TypeScript or C# is
how they lack a perfect analogue to Haskell's typeclasses. Let's use
Haskell's <code>Functor</code> typeclass as an example:</p>
<pre class="lang-hs prettyprint-override"><code>class Functor f where
    fmap :: (a -&gt; b) -&gt; f a -&gt; f b
</code></pre>
<p>The closest analogue in TypeScript would be an object conforming to
an interface like:</p>
<pre class="lang-typescript prettyprint-override"><code>interface Functor&lt;T&gt; {
  fmap &lt;U&gt;(func: (value: T) =&gt; U): Functor&lt;U&gt;
}
</code></pre>
<p>But here we run into a problem: TypeScript can't have a type constructor as a
type parameter and the interface instructs us only to
return <em>any</em> <code>Functor</code>, but this is not what we want a <code>Functor</code> to do. For
TypeScript the following is fully conformant to the <code>Functor</code> interface.</p>
<pre class="lang-typescript prettyprint-override"><code>class Box&lt;T&gt; implements Functor&lt;T&gt; {
  fmap &lt;U&gt;(func: (value: T) =&gt; U): UnrelatedFunctor&lt;U&gt; { /* ... */ }
}
</code></pre>
<p>In a simple type (without type parameter) this isn't a problem thanks to
polymorphic <code>this</code>:</p>
<pre class="lang-typescript prettyprint-override"><code>class Simple {
  doSomething (): this
}
class SimplEx extends Simple {}

const simEx: SimpleEx = // type is correct 
  new SimpleEx().doSomething() 
</code></pre>
<p>So for this to work we need to somehow reference our future implementing
type like Haskell does it; A &quot;forward&quot; parameter. By referencing this
parameter a type-checker would know we want an object conforming to the
implementing type, not the base-type.</p>
<p>In pseudo-TypeScript this could look something like:</p>
<pre class="lang-typescript prettyprint-override"><code>// `F`` &quot;inherits&quot; kind (* -&gt; *) from `Functor`
//                ∨
interface Functor(F)&lt;T&gt; {
  // now we apply our argument directly to this parameter
  //                               ∨
  fmap &lt;U&gt;(func: (value: T) =&gt; U): F&lt;U&gt;
}
</code></pre>
<p>So the questions I have are:</p>
<ol>
<li>Is that a sound solution to my problem or am I walking into a
dead-end without realizing it?</li>
<li>Is this intuitive, particularly for people without much experience in
Haskell-like languages or higher-order types?</li>
</ol>

<syntax><types><object-oriented><haskell><interfaces>
How to design interfaces to mimic haskell-like type classes in an object oriented language?
CC BY-SA 4.0
2024-01-04T19:11:45.033Z
Check out [F-bounds](https://en.wikipedia.org/wiki/Bounded_quantification). They're one approach to this problem in languages like Scala, but they don't go all the way (you could still do `class Box<T> extends Functor<UnrelatedFunctor>` (where `Functor` would be defined as taking a type constructor as an argument)
user
CC BY-SA 4.0
2024-01-04T19:14:51.620Z
Also, I'm not sure what this has to do with syntax. Are you asking for syntax options for higher-kinded types?
user
CC BY-SA 4.0
2024-01-04T20:04:43.177Z
@user You're right, it's really less of a syntax question than it is conceptual. Changed the title to reflect that. The syntax-part was mainly about how you could style this intuitively inside a more object oriented concept using classes and interfaces. I'm gonna check out F-bounds and Scala; from a short look that should be usefull, thanks.
Kilian Kilmister
CC BY-SA 4.0
2024-01-09T05:43:55.927Z
This question on SO might be related: https://stackoverflow.com/questions/35951818
raner
<p>If you can declare a type to be a member of a class <em>after</em> the type is declared, then what this means is that all of the information required by that membership (e.g. virtual dispatch tables) cannot be stored in the type itself.</p>
<p>At the point where the membership property is used in the program, at least one of two things must happen:</p>
<ul>
<li>It is resolved at compile time.</li>
<li>It is available at run-time via some other mechanism.</li>
</ul>
<p>An example of the first is <a href="https://en.cppreference.com/w/cpp/language/constraints" rel="nofollow noreferrer">constraints-and-concepts</a> in C++, which is a more-strongly-typed version of something that C++ programmers have been doing with templates since the 80s.</p>
<p>As for the second approach, there are essentially two possibilities: pass them as function arguments (possibly implicitly), or associate them with object references. This corresponds, more or less, to type constraints and existential types in Haskell respectively.</p>
<p>Passing virtual dispatch tables around as function arguments has a long history. It's essentially how the C bindings for distributed object systems (e.g. COM) work.</p>
<p>Existential types also have a long history. There are many C APIs where a function takes an opaque void pointer argument, which is an untyped version of this. Also consider the associated &quot;deleters&quot; in C++ smart pointers.</p>
<p>Before designing this into an imperative programming language, however, you should be aware that existential types interact subtly with mutable objects. Famously, the type system of Cyclone (an ancestor of Rust) was <a href="https://homes.cs.washington.edu/%7Edjg/papers/exists_imp.pdf" rel="nofollow noreferrer">broken for several months</a> until the flaw was spotted.</p>

CC BY-SA 4.0
2024-01-12T01:51:20.653Z
2024-01-12T01:51:20.653Z
Pseudonym
# How to design interfaces to mimic haskell-like type classes in an object oriented language?
Posted by: username_0 on 2024-01-04
A problem I sometimes run into when using a language like TypeScript or C# is
how they lack a perfect analogue to Haskell's typeclasses. Let's use
Haskell's Functor typeclass as an example:
class Functor f where
    fmap :: (a -> b) -> f a -> f b

The closest analogue in TypeScript would be an object conforming to
an interface like:
interface Functor {
  fmap (func: (value: T) => U): Functor
}

But here we run into a problem: TypeScript can't have a type constructor as a
type parameter and the interface instructs us only to
return any Functor, but this is not what we want a Functor to do. For
TypeScript the following is fully conformant to the Functor interface.
class Box implements Functor {
  fmap (func: (value: T) => U): UnrelatedFunctor { /* ... */ }
}

In a simple type (without type parameter) this isn't a problem thanks to
polymorphic this:
class Simple {
  doSomething (): this
}
class SimplEx extends Simple {}

const simEx: SimpleEx = // type is correct 
  new SimpleEx().doSomething() 

So for this to work we need to somehow reference our future implementing
type like Haskell does it; A "forward" parameter. By referencing this
parameter a type-checker would know we want an object conforming to the
implementing type, not the base-type.
In pseudo-TypeScript this could look something like:
// `F`` "inherits" kind (* -> *) from `Functor`
//                ∨
interface Functor(F) {
  // now we apply our argument directly to this parameter
  //                               ∨
  fmap (func: (value: T) => U): F
}

So the questions I have are:

Is that a sound solution to my problem or am I walking into a
dead-end without realizing it?
Is this intuitive, particularly for people without much experience in
Haskell-like languages or higher-order types?
**Tags:** syntax types object-oriented haskell interfaces
> **Comments:**
> **username_1**: Check out [F-bounds](https://en.wikipedia.org/wiki/Bounded_quantification). They're one approach to this problem in languages like Scala, but they don't go all the way (you could still do `class Box<T> extends Functor<UnrelatedFunctor>` (where `Functor` would be defined as taking a type constructor as an argument)  
> **username_1**: Also, I'm not sure what this has to do with syntax. Are you asking for syntax options for higher-kinded types?  
> **username_0**: @user You're right, it's really less of a syntax question than it is conceptual. Changed the title to reflect that. The syntax-part was mainly about how you could style this intuitively inside a more object oriented concept using classes and interfaces. I'm gonna check out F-bounds and Scala; from a short look that should be usefull, thanks.  
> **username_2**: This question on SO might be related: https://stackoverflow.com/questions/35951818  
---
## 1 answers
### Answer by username_3 on 2024-01-12. Score: 2
If you can declare a type to be a member of a class *after* the type is declared, then what this means is that all of the information required by that membership (e.g. virtual dispatch tables) cannot be stored in the type itself.

At the point where the membership property is used in the program, at least one of two things must happen:

* It is resolved at compile time.
* It is available at run-time via some other mechanism.

An example of the first is [constraints-and-concepts](https://en.cppreference.com/w/cpp/language/constraints) in C++, which is a more-strongly-typed version of something that C++ programmers have been doing with templates since the 80s.

As for the second approach, there are essentially two possibilities: pass them as function arguments (possibly implicitly), or associate them with object references. This corresponds, more or less, to type constraints and existential types in Haskell respectively.

Passing virtual dispatch tables around as function arguments has a long history. It's essentially how the C bindings for distributed object systems (e.g. COM) work.

Existential types also have a long history. There are many C APIs where a function takes an opaque void pointer argument, which is an untyped version of this. Also consider the associated "deleters" in C++ smart pointers.

Before designing this into an imperative programming language, however, you should be aware that existential types interact subtly with mutable objects. Famously, the type system of Cyclone (an ancestor of Rust) was [broken for several months](https://homes.cs.washington.edu/%7Edjg/papers/exists_imp.pdf) until the flaw was spotted.
---
