Liste (rappresentate da IEnumerable<T>
in .net) insieme a due operazioni formano una monade, che deve obbedire allo . Queste due operazioni hanno nomi diversi in diverse lingue, l'articolo di wikipedia usa Haskell che li chiama return
e >>=
(chiamato "bind"). C# chiama >>=
SelectMany
e non ha una funzione incorporata per return
. I nomi non sono importanti e ciò che conta sono i tipi. Specializzato per IEnumerable<T>
questi sono:
Return :: T -> IEnumerable<T>
SelectMany :: IEnumerable<T> -> Func<T, IEnumerable<U>> -> IEnumerable<U>
Return
restituisce semplicemente una sequenza 1 elementi contenente dell'elemento dato esempio
public static IEnumerable<T> Return<T>(T item)
{
return new[] { item };
}
SelectMany
è già implementata come Enumerable.SelectMany
:
public static IEnumerable<U> SelectMany<T, U>(IEnumerable<T> seq, Func<T, IEnumerable<U>> f) { ... }
SelectMany
prende una sequenza di immissione e una funzione che genera un'altra sequenza per ogni elemento della sequenza di input e appiattisce la sequenza risultante di sequenze in uno.
Riaffermando le prime due leggi monade in C# che abbiamo:
identità Sinistra
Func<T, IEnumerable<U>> f = ...
Return(x).SelectMany(f) == f(x)
identità destro
IEnumerable<T> seq = ...
seq.SelectMany(Return) == seq
Per la legge dell'identità destra, SelectMany
deve appiattire ogni sequenza generata dallo Func<T, IEnumerable<U>>
in base all'ordine degli elementi di input.
Si supponga di appiattirli nell'ordine inverso, ad es.
new[] { 1, 2 }.SelectMany(i => new[] { i, -i }) == new[] { 2, -2, 1, -1 }
poi
var s = new[] { 1, 2 }
s.SelectMany(Return) == new[] { 2, 1 } != s
che non avrebbe soddisfatto la legge giusta identità richiesto.
Come hai imparato questo? Sarei interessato a trovare la risorsa in cui hai ottenuto questo tipo di informazioni. –
@BigEndian aaaaa e non lo sapremo mai :) –
@BigEndian - Guarda l'aggiornamento. C'è anche una spiegazione delle leggi della monade sul [wiki Haskell] (https: //wiki.haskell.org/Monad_laws). Se vuoi saperne di più sulle monadi in generale, allora sono pervasive in Haskell e Scala. Normalmente, C# non fa riferimento ad essi poiché il sistema di tipi non può esprimere l'astrazione della monade ma è possibile trovare implementazioni per tipi particolari (ad esempio IEnumerable, IObservable , Task ). –
Lee