8
votes

Comment la monade peut-elle agir comme un court-circuit?

J'essaie d'obtenir une compréhension plus profonde des monades. J'ai donc commencé à creuser un peu dans la monade peut-être.

Il y a une chose que je ne semble pas avoir raison. Lisez ceci: p>

"de sorte que la liaison agit peut-être un court-circuit. Dans n'importe quelle chaîne d'opérations, si l'une quelconque d'entre elles ne renvoie rien, l'évaluation cessera et rien ne sera retourné de toute la chaîne . " em> p>

de: http://mikehadlow.blogspot.com/2011/01/monads-in-c-5-maybe.html p>

et ceci: p>

"Pour le type peut être code>, la liaison est implémentée en fonction de la règle aussi simple: si la chaîne renvoie une valeur vide à un moment donné, d'autres étapes de la chaîne sont ignorées et une valeur vide est réactionnelle à la place. " em> p>

de:" Programmation fonctionnelle en C # " http : //www.amazon.com/fonctionnel-programming-techniques-projects-programmer/dp/0470744588/ P>

OK, regardons le code. Voici mon peut-être monade: p> xxx pré>

et voici mon exemple de code à l'aide de la monad: p> xxx pré>

Il est clair de voir que nous essayons de creuser plus profondément dans le nœud que possible. Cependant, je ne vois pas comment il agit selon les citations que j'ai mentionnées. Je veux dire, bien sûr, j'ai pris en compte les chèques nuls et l'exemple fonctionne. Cependant, il ne casse pas la chaîne tôt. Si vous définissez des points d'arrêt, vous verrez que chaque opération Bind () code> sera utilisée ainsi sans valeur pour les dernières opérations. Mais cela signifie que si je creusai du niveau de niveau profond et que cela ne diminue réellement que 3 niveaux, je vérifierai toujours 20 niveaux ou je me trompe? P>

comparer ceci à l'approche non monad: p> XXX PRE>

N'est-ce pas en réalité ce qu'on doit appeler un court-circuit? Parce que dans ce cas, le cas échéant si vraiment au niveau où la première valeur est nulle. P>

Can quelqu'un peut m'aider à obtenir cette clair? P>

Mise à jour strong>

Comme Patrik a souligné, oui, il est vrai que chaque liaison sera invoquée même si nous n'avions que 3 niveaux et essayons de passer 20 niveaux profonds. Cependant, l'expression réelle fournie à l'appel BIND () ne sera pas évaluée. Nous pouvons éditer l'exemple pour effacer l'effet: P>

        var childNode = node.ChildNode
            .ToMaybe()
            .Bind(x =>
                      {
                          Console.WriteLine("We will see this");
                          return x.ChildNode.ToMaybe();
                      })
            .Bind(x => x.ChildNode.ToMaybe())
            .Bind(x => x.ChildNode.ToMaybe())
            .Bind(x => x.ChildNode.ToMaybe())
            .Bind(x =>
                      {
                          Console.WriteLine("We won't see this");
                          return x.ChildNode.ToMaybe();
                      });


0 commentaires

3 Réponses :


5
votes

Si je comprends bien, tous les méthodes lidez seront invoqués, mais les expressions fournies ne seront évaluées que si la précédente renvoie une valeur. Cela signifie que méthodes appelés après un qui renvoie null (ou plus correctement: par défaut (t) ) sera très bon marché. < / p>


1 commentaires

Merci pour votre réponse. Oui, tu as raison. Mais Patrik Répondre rend encore plus clair. Je t'ai toujours donné un uppote ;-)



12
votes

J'ai une mise en œuvre de la monade peut-être en C # qui diffère un peu du vôtre, tout d'abord, il n'est pas lié à des chèques nuls, je pense que ma mise en œuvre ressemble plus à ce qui se passe dans une norme peut-être la mise en œuvre, par exemple, Haskel. Ma mise en œuvre: P>

public static class Maybe
{
    public static Maybe<T> NotNull<T>(T value) where T : class
    {
        return value != null ? Maybe<T>.Just(value) : Maybe<T>.Nothing;
    }

    public static Maybe<string> NotEmpty(string value)
    {
        return value.Length != 0 ? Maybe<string>.Just(value) : Maybe<string>.Nothing;
    }


}

string foo = "whatever";
Maybe.NotNull(foo).Bind(x => Maybe.NotEmpty(x)).Bind(x => { Console.WriteLine(x); return Maybe<string>.Just(x); });


1 commentaires

Réponse géniale. En particulier mettre dans la console.writeine ​​() le rend cristallin clair. +1 Pour les informations supplémentaires que vous avez présentées.



0
votes

Nous pouvons le faire plus de ruse.

interface d'écriture dérivée d'iEnumerable xxx

Ceci enregistrera la compatibilité avec les méthodes LINQ xxx

après cela, nous pouvons utiliser Pouvoir pleine puissance de Linq et faites comme ça xxx


0 commentaires