Sacar la programación funcional C # --3

prefacio

Alguien hoy y conversó con el C # LINQ, LINQ LINQ encuentro Sé que parece como la mayoría de las personas no saben lo mismo, cómo una ley diferente? De hecho, LINQ también se puede utilizar para participar en la programación funcional.

Por supuesto, no quiere decir unas pocas escritura lambday similares con el uso de Java como streamtales, incluso si el llamado LINQ, LINQ es en realidad una otra cosa.

LINQ

En C #, LINQ Creo que hemos visto la siguiente redacción:

IEnumerable<int> EvenNumberFilter(IEnumerable<int> list)
{
    return from c in list where c & 1 == 0 select c;
}

Con la sintaxis de LINQ por encima de los implementos de código de una lista de cribado, incluso.

LINQ es sólo un conjunto de herramientas que se utilizan para facilitar la operación de la misma, si queremos que nuestro propio si el tipo de sintaxis de soporte LINQ, entonces tenemos que lograr nuestro tipo IEnumerable<T>, entonces puede estar tan acostumbrado. . .

Oh, es cierto? Entiendo todo eso. . . . . .

? ? ? Oh, Dios mío, por supuesto que no!

De hecho, LINQ y IEnumerable<T>no tiene nada que ver! LINQ es sólo un conjunto de extensiones único método, que se compone principalmente de los métodos siguientes:

nombre del método Descripción del método
Dónde filtrado de datos
Seleccionar / SelectMany proyector de datos
Join / GroupJoin conexión de datos
OrdenarPor / ThenBy / OrderByDescending / ThenByDescending Ordenación de datos
Agrupar por Los paquetes de datos
......

El método anterior corresponde LINQ Palabras clave: where, select, join, orderby, group...

Cuando el compilador compila código C # que convertirá LINQ sintaxis de llamadas a métodos de extensión de sintaxis, por ejemplo:

from c in list where c > 5 select c;

Se compila en:

list.Where(c => c > 5).Select(c => c);

Para otro ejemplo:

from x1 in list1 join x2 in list2 on x1.k equals x2.k into g select g.u;

Se compila en:

list1.GroupJoin(list2, x1 => x1.k, x2 => x2.k, (x1, g) => g.u);

Para otro ejemplo:

from x in list orderby x.k1, x.k2, x.k3;

Se compila en:

list.OrderBy(x => x.k1).ThenBy(x => x.k2).ThenBy(x => x.k3);

Una vez más:

from c in list1
from d in list2
select c + d;

Se compila en:

list1.SelectMany(c => list2, (c, d) => c + d);

Parada, parada!

Además, el compilador en tiempo de compilación siempre será primero y luego llamar a la traducción sintaxis LINQ compilado como un método, a continuación, siempre y cuando el nombre del método correspondiente, no significa que usted puede utilizar la sintaxis de LINQ (escape

Así que ya ves este SelectManyno lo es. . .

jpg

SelectMany es Monad

Oh, Dios mío, nos fijamos en este pobre SelectMany, esto no Monadse requiere bindla función?

Poco a poco las cosas se ponen interesantes de nuevo.

Hemos heredado el espíritu de uno, escribir de nuevo Maybe<T>.

Maybe<T>

En primer lugar, se escribe una clase abstracta Maybe<T>.

En primer lugar, tenemos que añadir a un Selectmétodo para la selección de los Maybe<T>datos, si es T, entonces un retorno Just<T>, si es Nothing<T>, entonces un retorno Nothing<T>. El equivalente de nuestra returnsfunción:

public abstract class Maybe<T>
{
    public abstract Maybe<U> Select<U>(Func<T, Maybe<U>> f);
}

Entonces nos damos cuenta de nuestra Juste Nothing:

public class Just<T> : Maybe<T>
{
    private readonly T value;
    public Just(T value) { this.value = value; }

    public override Maybe<U> Select<U>(Func<T, Maybe<U>> f) => f(value);
    public override string ToString() => $"Just {value}";
}

public class Nothing<T> : Maybe<T>
{
    public override Maybe<U> Select<U>(Func<T, Maybe<U>> _) => new Nothing<U>();
    public override string ToString() => "Nothing";
}

Entonces, tenemos que Maybedarnos cuenta bind- que es, al Maybeañadir un conocido SelectManymétodo.

public abstract class Maybe<T>
{
    public abstract Maybe<U> Select<U>(Func<T, Maybe<U>> f);

    public Maybe<V> SelectMany<U, V>(Func<T, Maybe<U>> k, Func<T, U, V> s)
        => Select(x => k(x).Select(y => new Just<V>(s(x, y))));
}

Hasta ahora, Maybe<T>conseguido a lo largo! Lo que, en este? ? Entonces, ¿cómo se usa? Momento emocionante que viene!

En primer lugar, creamos unos cuantos Maybe<int>:

var x = new Just<int>(3);
var y = new Just<int>(7);
var z = new Nothing<int>();

A continuación, se calcularon utilizando el LINQ x + y, x + z:

var u = from x0 in x from y0 in y select x0 + y0;
var v = from x0 in x from z0 in z select x0 + z0;

Console.WriteLine(u);
Console.WriteLine(v);

salida:

Just 10
Nothing

Perfecto! El LINQ anteriormente compilado como:

var u = x.SelectMany(_ => y, (x0, y0) => x0 + y0);
var v = x.SelectMany(_ => z, (x0, z0) => x0 + z0);

En este momento, las funciones kcomo int -> Maybe<int>, y la función sque (int, int) -> int, además de una función.

Función kparámetros que no me importa, que se utiliza como selector, sólo tenemos que generar una marca Maybe<int>, y luego usar la función sde los dos intvalores hacemos víbora, y los resultados en un abarrotado Just<int>dentro de la lata.

Este proceso, si no se producen o bien Nothing, el resultado es siempre la operación de seguimiento Nothing, porque Nothing.Select(...)todavía Nothing.

Una pequeña extensión

Damos este Maybe<T>más un Where:

public abstract class Maybe<T>
{
    public abstract Maybe<U> Select<U>(Func<T, Maybe<U>> f);

    public Maybe<V> SelectMany<U, V>(Func<T, Maybe<U>> k, Func<T, U, V> s)
        => Select(x => k(x).Select(y => new Just<V>(s(x, y))));

    public Maybe<U> Where(Func<Maybe<T>, bool> f) => f(this) ? this : new Nothing<T>();
}

Entonces podemos jugar:

var just = from c in x where true select c;
var nothing = from c in x where false select c;

Console.WriteLine(just);
Console.WriteLine(nothing);

Cuando la condición devuelve Just, de lo contrario devuelve Nothing. Por encima de la salida:

Just 3
Nothing

Hay un olor en el interior (escape

posdata

Los siguientes artículos de esta serie serán escritos en la hipoteca, si C # decepcionante que los sindicatos discriminado, Superior Kinded genéricos y tipo de características Clases más, y seguimos.

Supongo que te gusta

Origin www.cnblogs.com/hez2010/p/12590389.html
Recomendado
Clasificación