Type d'unité - Unit type
Dans le domaine de la logique mathématique et de l' informatique connu sous le nom de théorie des types , un type unitaire est un type qui n'autorise qu'une seule valeur (et ne peut donc contenir aucune information). Le transporteur (ensemble sous-jacent) associé à un type d'unité peut être n'importe quel ensemble singleton . Il existe un isomorphisme entre deux de ces ensembles, il est donc habituel de parler du type d'unité et d'ignorer les détails de sa valeur. On peut aussi considérer le type unitaire comme le type des 0- uplets , c'est-à-dire le produit de aucun type.
Le type d'unité est l' objet terminal dans la catégorie des types et des fonctions typées. Il ne faut pas le confondre avec le type zero ou bottom , qui n'autorise aucune valeur et est l' objet initial de cette catégorie. De même, le booléen est le type à deux valeurs.
Le type d'unité est implémenté dans la plupart des langages de programmation fonctionnels . Le type void utilisé dans certains langages de programmation impératifs remplit certaines de ses fonctions, mais comme son ensemble de supports est vide, il présente certaines limitations (comme détaillé ci-dessous).
Dans les langages de programmation
Plusieurs langages de programmation informatique fournissent un type d'unité pour spécifier le type de résultat d'une fonction dans le seul but de provoquer un effet secondaire , et le type d'argument d'une fonction qui ne nécessite pas d'arguments.
- Dans Haskell , Rust et Elm , le type d'unité est appelé
()et sa seule valeur est également(), reflétant l'interprétation 0-uplet. - Dans les descendants de ML (y compris OCaml , Standard ML et F# ), le type est appelé
unitmais la valeur est écrite sous la forme(). - En Scala , le type d'unité est appelé
Unitet sa seule valeur est écrite sous la forme(). - En Common Lisp, le type nommé NULL est un type d'unité qui a une valeur, à savoir le symbole NIL . Cela ne doit pas être confondu avec le type NIL , qui est le type inférieur .
- En Python , il existe un type appelé
NoneTypequi autorise la valeur unique deNone. - Dans Swift , le type d'unité est appelé
Voidor()et sa seule valeur est également(), reflétant l'interprétation 0-tuple. - En Java , le type d'unité est appelé
Voidet sa seule valeur estnull. - Dans Go , le type d'unité est écrit
struct{}et sa valeur eststruct{}{}. - En PHP , le type d'unité est appelé null, dont la seule valeur est NULL elle-même.
- En JavaScript ,
Null(sa seule valeur estnull) etUndefined(sa seule valeur estundefined) sont des types d'unité intégrés. - dans Kotlin ,
Unitest un singleton avec une seule valeur : l'Unitobjet. - En Ruby ,
nilest la seule instance de laNilClassclasse. - En C++ , le
std::monostatetype d'unité a été ajouté en C++17. Avant cela, il est possible de définir un type d'unité personnalisé à l'aide d'une structure vide telle questruct empty{}.
Type de vide comme type d'unité
En C , C++ , C# et D , voidest utilisé pour désigner une fonction qui ne retourne rien d'utile, ou une fonction qui n'accepte aucun argument. Le type d'unité en C est conceptuellement similaire à un empty struct, mais une structure sans membres n'est pas autorisée dans la spécification du langage C (cela est autorisé en C++). Au lieu de cela, ' void' est utilisé d'une manière qui simule certaines, mais pas toutes, les propriétés du type d'unité, comme détaillé ci-dessous. Comme la plupart des langages impératifs, C autorise les fonctions qui ne renvoient pas de valeur ; ceux-ci sont spécifiés comme ayant le type de retour void. De telles fonctions sont appelées procédures dans d'autres langages impératifs comme Pascal , où une distinction syntaxique, au lieu d'une distinction de système de types, est faite entre les fonctions et les procédures.
Différence dans la convention d'appel
La première différence notable entre un vrai type unit et le type void est que le type unit peut toujours être le type de l'argument d'une fonction, mais le type void ne peut pas être le type d'un argument en C, malgré le fait qu'il puisse apparaissent comme le seul argument dans la liste. Ce problème est mieux illustré par le programme suivant, qui est une erreur de compilation en C :
void f(void) {}
void g(void) {}
int main(void)
{
f(g()); // compile-time error here
return 0;
}
Ce problème ne se pose pas dans la plupart des pratiques de programmation en C, car puisque le voidtype ne porte aucune information, il est de toute façon inutile de le transmettre ; mais il peut survenir dans la programmation générique , comme les modèles C++ , où voiddoit être traité différemment des autres types. En C++ cependant, les classes vides sont autorisées, il est donc possible d'implémenter un type d'unité réel ; l'exemple ci-dessus devient compilable en tant que :
class unit_type {};
const unit_type the_unit;
unit_type f(unit_type) { return the_unit; }
unit_type g(unit_type) { return the_unit; }
int main()
{
f(g(the_unit));
return 0;
}
(Par souci de concision, nous ne sommes pas inquiets dans l'exemple ci-dessus s'il the_units'agit vraiment d'un singleton ; voir le modèle de singleton pour plus de détails sur ce problème.)
Différence de stockage
La deuxième différence notable est que le type void est spécial et ne peut jamais être stocké dans un type record , c'est-à-dire dans une structure ou une classe en C/C++. En revanche, le type d'unité peut être stocké dans des enregistrements dans des langages de programmation fonctionnels, c'est-à-dire qu'il peut apparaître comme le type d'un champ ; l'implémentation ci-dessus du type d'unité en C++ peut également être stockée. Bien que cela puisse sembler une fonctionnalité inutile, cela permet, par exemple, d'implémenter élégamment un ensemble en tant que correspondance avec le type d'unité ; en l'absence d'un type d'unité, on peut toujours implémenter un ensemble de cette manière en stockant une valeur fictive d'un autre type pour chaque clé.
Dans les génériques
Dans Java Generics, les paramètres de type doivent être des types de référence. Le type wrapper Voidest souvent utilisé lorsqu'un paramètre de type d'unité est nécessaire. Bien que le Voidtype ne puisse jamais avoir d'instances, il a une valeur null(comme tous les autres types de référence), il agit donc comme un type d'unité. En pratique, tout autre type non instanciable, par exemple Math, peut également être utilisé à cette fin, car ils ont également exactement une valeur, null.
public static Void f(Void x) { return null; }
public static Void g(Void x) { return null; }
public static void main(String[] args)
{
f(g(null));
}
Voir également
- Modèle singleton (où une classe particulière n'a qu'une seule instance, mais les références non nullables de type étroit ne sont généralement pas détenues par d'autres classes)
Les références
- Pierce, Benjamin C. (2002). Types et langages de programmation . MIT Appuyez sur . p. 118–119. ISBN 0-262-16209-1.
- type d'unité dans nLab