Il fait juste un type normal constructeur qui arrive à être défini dans le Prélude, qui est la bibliothèque standard, qui est automatiquement importé dans chaque module.
Ce qui est Peut-être, Structurellement
La définition ressemble à quelque chose comme ceci:
data Maybe a = Just a
| Nothing
Cette déclaration définit un type, Maybe a
, ce qui est paramétrée par un type de variable a
, ce qui signifie simplement que vous pouvez l'utiliser avec n'importe quel type à la place de a
.
La construction et la Destruction
Le type a deux constructeurs, Just a
et Nothing
. Quand un type a plusieurs constructeurs, cela signifie qu'une valeur de type doit avoir été construit avec juste l'un des constructeurs. Pour ce type, une valeur était construite à l'aide d' Just
ou Nothing
, il n'y a pas d'autres (sans erreur) possibilités.
Depuis Nothing
n'a pas de type de paramètre, lorsqu'il est utilisé en tant que constructeur, c'est le nom d'une valeur constante qui est un membre de type Maybe a
pour tous les types a
. Mais l' Just
constructeur a un paramètre de type, ce qui signifie que lorsqu'il est utilisé en tant que constructeur, il agit comme une fonction de type a
de Maybe a
, c'est le type a -> Maybe a
Ainsi, les constructeurs d'un type de construire une valeur de ce type; de l'autre côté des choses, c'est quand vous voulez utiliser cette valeur, et c'est là que le pattern matching entre en jeu. Contrairement aux fonctions, les constructeurs peuvent être utilisés dans le modèle des expressions de liaison, et ce est la façon dont vous pouvez faire l'analyse du cas de valeurs qui appartiennent à des types avec plus d'un constructeur.
À l'utilisation de l' Maybe a
de la valeur dans un motif, vous devez fournir un modèle pour chaque constructeur, comme suit:
case maybeVal of
Nothing -> "There is nothing!"
Just val -> "There is a value, and it is " ++ (show val)
Dans ce cas, l'expression, le premier modèle serait de match si la valeur est Nothing
, et le second serait de match si la valeur a été construit avec des Just
. Si le second correspond, il se lie également le nom d' val
pour le paramètre qui a été transmis à l' Just
constructeur lorsque la valeur que vous êtes correspondant à contre a été construit.
Ce Qui Signifie Peut-Être
Peut-être vous étiez déjà familier avec la façon dont cela a fonctionné; il n'y a pas vraiment de magie Maybe
valeurs, c'est juste normal Haskell Algébrique de Type de Données (ADT). Mais c'est utilisé un peu, parce qu'il fait des "ascenseurs", ou qui s'étend d'un type, comme Integer
de votre exemple, dans un nouveau contexte dans lequel il a une valeur supplémentaire (Nothing
) qui représente un manque de valeur! Le type de système nécessite que vous vérifiez que la valeur supplémentaire avant de vous laisser à l' Integer
qui pourrait être là. Cela empêche un grand nombre de bugs.
De nombreuses langues aujourd'hui gérer ce genre de "non-valeur" valeur via des références NULLES. Tony Hoare, un éminent chercheur en informatique (il a inventé Quicksort et est un de Turing Award winner), propriétaire jusqu'à ce que son "milliards de dollars erreur". Peut-être le type n'est pas le seul moyen de résoudre ce problème, mais il s'est avéré être un moyen efficace de le faire.
Peut-être comme un Foncteur
L'idée de transformer un type à l'autre, telles que les opérations sur le vieux type peut également être transformé à travailler sur le nouveau type est le concept derrière le Haskell type de classe appelé Functor
, Maybe a
a un utile exemple de.
Functor
fournit une méthode appelée fmap
, qui associe les fonctions de la gamme de valeurs du type de base (tels que l' Integer
) à des fonctions qui vont sur les valeurs de la levée de type (comme Maybe Integer
). Une fonction transformée avec fmap
de travailler sur un Maybe
de la valeur des œuvres comme ceci:
case maybeVal of
Nothing -> Nothing -- there is nothing, so just return Nothing
Just val -> Just (f val) -- there is a value, so apply the function to it
Donc, si vous avez un Maybe Integer
valeur m_x
et Int -> Int
fonction f
, vous pouvez le faire fmap f m_x
appliquer la fonction f
directement à l' Maybe Integer
sans se soucier de savoir si c'est effectivement une valeur ou non. En fait, vous pouvez appliquer un ensemble de la chaîne de levé Integer -> Integer
fonctions d' Maybe Integer
valeurs et ont seulement à vous soucier explicitement vérifiant Nothing
une fois lorsque vous avez terminé.
Peut-être comme une Monade
Je ne suis pas sûr de savoir comment vous vous serez familiarisé avec le concept de l' Monad
encore, mais vous avez au moins utilisée, IO a
avant, et la signature de type IO a
semble remarquablement similaire Maybe a
. Bien qu' IO
a pour particularité de ne pas exposer ses constructeurs pour vous, et ne peut donc être "exécuté" par le Haskell système d'exécution, c'est toujours aussi un Functor
en plus d'être un Monad
. En fait, il y a un sens important dans lequel un Monad
est juste un type spécial d' Functor
avec quelques fonctionnalités supplémentaires, mais ce n'est pas le lieu d'entrer dans cette.
De toute façon, les Monades comme IO
types de carte à de nouveaux types qui représentent "les calculs qui en résultent dans les valeurs" et vous pouvez soulever des fonctions en Monad
types via une très fmap
-comme la fonction appelée liftM
qui transforme une fonction régulière dans un "calcul qui aboutit à la valeur obtenue par l'évaluation de la fonction."
Vous l'avez probablement deviné (si vous avez lu jusqu'ici) Maybe
est aussi un Monad
. Il représente "calculs qui pourrait ne pas renvoyer une valeur". Tout comme avec l' fmap
exemple, cela vous permet de faire tout un tas de calculs sans avoir explicitement vérifier pour les erreurs après chaque étape. Et en fait, la façon dont l' Monad
exemple est construit, un calcul sur Maybe
valeurs s'arrête dès qu'un Nothing
est rencontré, c'est un peu comme un abandon immédiat ou sans valeur de retour dans le milieu d'un calcul.
Vous Auriez Pu Écrire Peut-Être
Comme je l'ai dit avant, il n'y a rien d'inhérent à l' Maybe
type qui est cuit dans la syntaxe de la langue ou de l'exécution du système. Si Haskell n'ai pas fourni par défaut, vous pouvez fournir l'ensemble de ses fonctionnalités vous-même! En fait, vous pouvez l'écrire à nouveau vous-même, avec des noms différents, et obtenir la même fonctionnalité.
J'espère que vous comprenez l' Maybe
type et ses constructeurs maintenant, mais si il y a encore quelque chose de pas clair, faites le moi savoir!