L' une des propriétés définissant des ⊥ type ou vide est qu'il existe une fonction ⊥ → A pour chaque type UNE . En fait, il existe une telle fonction unique . Il est donc assez raisonnable que cette fonction soit fournie dans le cadre de la bibliothèque standard. Souvent, cela s'appelle quelque chose comme absurd
. (Dans les systèmes avec sous-typage, cela peut être géré simplement en ayant ⊥ un sous-type de chaque type. Ensuite, la conversion implicite est absurd
. Une autre approche connexe consiste à définir ⊥ comme ∀ α . α qui peut simplement être instancié à n'importe quel type.)
⊥E+ AEthrow:E→⊥Af:A→BB⊥Babsurd
⊥→Aabsurd
absurd
⊥→A
Même s'il n'y a pas beaucoup de raisons d'écrire une telle fonction, elle devrait généralement être autorisée . L'une des raisons est qu'il simplifie les outils / macros de génération de code.
Derek Elkins a quitté SE
la source
(x ? 3 : throw new Exception())
est remplacé à des fins d'analyse par quelque chose de plus(x ? 3 : absurd(throw new Exception()))
?absurd
absurd
throw
Pour ajouter à ce qui a été dit sur la fonction,
absurd: ⊥ -> a
j'ai un exemple concret où cette fonction est réellement utile.Considérons le type de données Haskell
Free f a
qui représente une structure arborescente générale avec desf
nœuds en forme de feuilles et des feuilles contenanta
s:data Free f a = Op (f (Free f a)) | Var a
Ces arbres peuvent être pliés avec la fonction suivante:
Brièvement, cette opération se place
alg
aux nœuds etgen
aux feuilles.Maintenant au point: toutes les infrastructures de données récursives peuvent être représentées en utilisant un type de données à virgule fixe. Dans Haskell, c'est
Fix f
et cela peut être défini commetype Fix f = Free f ⊥
(c'est-à-dire des arbres avec desf
nœuds en forme et sans feuilles à l'extérieur du foncteurf
). Traditionnellement, cette structure a également un pli, appelécata
:Ce qui donne une utilisation assez soignée de l'absurde: puisque l'arbre ne peut pas avoir de feuilles (puisque ⊥ n'a pas d'habitants autres que
undefined
), il n'est jamais possible d'utiliser legen
pour ce pli etabsurd
illustre cela!la source
Le type inférieur est un sous-type de tous les autres types, ce qui peut être extrêmement utile dans la pratique. Par exemple, le type de
NULL
dans une version théorique sûre de type de C doit être un sous-type de tout autre type de pointeur, sinon vous ne pourriez pas, par exemple, retournerNULL
où achar*
était attendu; de la même manière, le type deundefined
code JavaScript de type sécurisé théorique doit être un sous-type de tous les autres types du langage.exit()
throw()
Int
Int
exit()
la source
NULL
est un type d'unité n'est-ce pas, différent de ⊥ qui est le type vide?void*
, vous auriez besoin d'un type spécifique qui pourrait être utilisé pour n'importe quel type de pointeur.<:
Il y a une utilisation à laquelle je peux penser, et c'est quelque chose qui a été considéré comme une amélioration du langage de programmation Swift.
Swift a une
maybe
Monade, orthographiéeOptional<T>
ouT?
. Il existe de nombreuses façons d'interagir avec.Vous pouvez utiliser le déballage conditionnel comme
Vous pouvez utiliser
map
,flatMap
pour transformer les valeurs!
, de type(T?) -> T
) pour dérouler le contenu avec force, déclenchant sinon un crashL'opérateur coalescent nul (
??
, de type(T?, T) -> T
) pour prendre sa valeur ou utiliser une valeur par défaut:Malheureusement, il n'y avait aucun moyen concis de dire "déballer ou jeter une erreur" ou "déballer ou planter avec un message d'erreur personnalisé". Quelque chose comme
ne compile pas, car
fatalError
a un type() -> Never
(()
estVoid
, le type d'unité deNever
Swift , est le type inférieur de Swift). L'appeler produitNever
, ce qui n'est pas compatible avec l'T
attendu comme opérande droit de??
.Pour tenter d'y remédier, Swift Evolution propsoal
SE-0217
- L'opérateur «Déballer ou mourir» a été proposé. Il a finalement été rejeté , mais il a suscité l'intérêt de faire de ceNever
type un sous-type de tous types.Si a
Never
été créé pour être un sous-type de tous types, alors l'exemple précédent sera compilable:car le site d'appel de
??
type a(T?, Never) -> T
, ce qui serait compatible avec la(T?, T) -> T
signature de??
.la source
Swift a un type "Never" qui semble être tout à fait comme le type du bas: Une fonction déclarée comme retournant Never ne peut jamais retourner, une fonction avec un paramètre de type Never ne peut jamais être appelée.
Ceci est utile en relation avec les protocoles, où il peut y avoir une restriction en raison du système de type du langage qu'une classe doit avoir une certaine fonction, mais sans aucune exigence que cette fonction soit appelée, et aucune exigence quant aux types d'arguments serait.
Pour plus de détails, vous devriez jeter un œil aux nouveaux articles de la liste de diffusion de swift-evolution.
la source