Je suis toujours un noob in Scala Development, mais j'ai trouvé l'option La vraie question est, où est la théorie derrière cet objet? Est-ce quelque chose de spécifique de Scala? Langues fonctionnelles? Où puis-je en trouver plus à ce sujet? P>
3 Réponses :
La plupart du temps, je pensais que cela vient du haskell, et a un nom de Peut-être em> monad p>
Mais après une petite recherche, j'ai constaté qu'il y avait des références sur les types d'options dans les papiers SML, comme indiqué @shidoisi. De plus, il a la même sémantique (certaines / aucune) que Scala a.
Le papier plus âgé que j'ai pu trouver est que a > (circa '89) (voir note de bas de page sur la 6ème page) P>
Wikipedia est votre ami: http://en.wikipedia.org/wiki/option_type p>
Malheureusement, cela ne donne pas de dates, mais je parierais que c'est ML-Origine prédate Haskell peut-être code>. P>.
Vous n'avez pas besoin de correspondance de modèle pour utiliser l'option. Je l'ai écrit en C # pour vous ci-dessous. Notez que la fonction La correspondance de modèle est généralement découragée en faveur des combinaisons de niveau supérieur. Par exemple, si votre fonction particulière peut être écrite à l'aide de pli code> prend en charge tout ce qui serait autrement assorti de modèle.
SELECT CODE>, vous l'utiliseriez plutôt que
pli code> (ce qui équivaut à la correspondance de modèle). Sinon, en supposant que le code sans effet secondaire (et donc raisonnement équivalent), vous seriez essentiellement à la ré-mise en œuvre du code existant. Cela détient toutes les langues, pas seulement Scala ou C #. P>
using System;
using System.Collections;
using System.Collections.Generic;
namespace Example {
/// <summary>
/// An immutable list with a maximum length of 1.
/// </summary>
/// <typeparam name="A">The element type held by this homogenous structure.</typeparam>
/// <remarks>This data type is also used in place of a nullable type.</remarks>
public struct Option<A> : IEnumerable<A> {
private readonly bool e;
private readonly A a;
private Option(bool e, A a) {
this.e = e;
this.a = a;
}
public bool IsEmpty {
get {
return e;
}
}
public bool IsNotEmpty{
get {
return !e;
}
}
public X Fold<X>(Func<A, X> some, Func<X> empty) {
return IsEmpty ? empty() : some(a);
}
public void ForEach(Action<A> a) {
foreach(A x in this) {
a(x);
}
}
public Option<A> Where(Func<A, bool> p) {
var t = this;
return Fold(a => p(a) ? t : Empty, () => Empty);
}
public A ValueOr(Func<A> or) {
return IsEmpty ? or() : a;
}
public Option<A> OrElse(Func<Option<A>> o) {
return IsEmpty ? o() : this;
}
public bool All(Func<A, bool> f) {
return IsEmpty || f(a);
}
public bool Any(Func<A, bool> f) {
return !IsEmpty && f(a);
}
private A Value {
get {
if(e)
throw new Exception("Value on empty Option");
else
return a;
}
}
private class OptionEnumerator : IEnumerator<A> {
private bool z = true;
private readonly Option<A> o;
private Option<A> a;
internal OptionEnumerator(Option<A> o) {
this.o = o;
}
public void Dispose() {}
public void Reset() {
z = true;
}
public bool MoveNext() {
if(z) {
a = o;
z = false;
} else
a = Option<A>.Empty;
return !a.IsEmpty;
}
A IEnumerator<A>.Current {
get {
return o.Value;
}
}
public object Current {
get {
return o.Value;
}
}
}
private OptionEnumerator Enumerate() {
return new OptionEnumerator(this);
}
IEnumerator<A> IEnumerable<A>.GetEnumerator() {
return Enumerate();
}
IEnumerator IEnumerable.GetEnumerator() {
return Enumerate();
}
public static Option<A> Empty {
get {
return new Option<A>(true, default(A));
}
}
public static Option<A> Some(A t) {
return new Option<A>(false, t);
}
}
}
"La correspondance de modèle est généralement découragée en faveur des combinaisons de niveau supérieur" - Je trouve que cela est généralement vrai avec la communauté Scala, bien que personnellement, je suis fortement en désaccord avec cette notion.
Ce n'est pas une déclaration controversée.
Et quand Tony Morris dit que quelque chose n'est pas une déclaration controversée, cela signifie quelque chose (quoique pas nécessairement ce qu'il a dit).
Fournir votre quantité habituelle de perspicacité et d'utilité que je vois.
En toute justice, vous n'avez pas besoin de la correspondance de modèle pour la majeure partie de l'ampleur de l'option. Vous avez juste besoin de covariance de site de déclaration, d'un type de bas, de lambdas et de paresseux. Utilisez la carte + getorelse au lieu du match de motif
En effet. J'utilise l'option tout le temps en C #, il convient bien à Linq.
@OXBOW_LAKES: Qu'est-ce que ce genre de choses a à voir avec la génialité de l'option? Lambdas, peut-être, à utiliser avec carte, mais qu'est-ce que | i> et la paresse a à voir avec ça?