Question

Certains problèmes sont facilement résolus par les types de données algébriques, par exemple un type de liste peut être très succinctement exprimé comme:

data ConsList a = Empty | ConsCell a (ConsList a)

consmap f Empty          = Empty
consmap f (ConsCell a b) = ConsCell (f a) (consmap f b)

l = ConsCell 1 (ConsCell 2 (ConsCell 3 Empty))
consmap (+1) l

Cet exemple particulier est dans Haskell, mais il serait similaire dans d'autres langues avec une prise en charge native pour les types de données algébriques.

Il s'avère qu'il existe une cartographie évidente dans le sous-type de style OO: le type de données devient une classe de base abstraite et chaque constructeur de données devient une sous-classe concrète. Voici un exemple dans Scala:

sealed abstract class ConsList[+T] {
  def map[U](f: T => U): ConsList[U]
}

object Empty extends ConsList[Nothing] {
  override def map[U](f: Nothing => U) = this
}

final class ConsCell[T](first: T, rest: ConsList[T]) extends ConsList[T] {
  override def map[U](f: T => U) = new ConsCell(f(first), rest.map(f))
}

val l = (new ConsCell(1, new ConsCell(2, new ConsCell(3, Empty)))
l.map(1+)

La seule chose nécessaire au-delà de la sous-classe naïve est un moyen de sceller Cours, c'est-à-dire un moyen de rendre impossible d'ajouter des sous-classes à une hiérarchie.

Comment aborderiez-vous ce problème dans une langue comme C # ou Java? Les deux pierres d'achoppement que j'ai trouvées lorsqu'ils essayaient d'utiliser les types de données algébriques en C # étaient:

  • Je ne pouvais pas comprendre comment le type inférieur est appelé dans C # (c'est-à-dire que je ne pouvais pas comprendre dans quoi mettre class Empty : ConsList< ??? >)
  • Je ne pouvais pas trouver un moyen de sceller ConsList afin qu'aucune sous-classe ne puisse être ajoutée à la hiérarchie

Quel serait le moyen le plus idiomatique d'implémenter les types de données algébriques en C # et / ou Java? Ou, si ce n'est pas possible, quel serait le remplacement idiomatique?

Pas de solution correcte

Licencié sous: CC-BY-SA avec attribution
scroll top