2009-05-28 14 views
4

Während ich tiefer in die neueste Version von F # eindringe, habe ich versucht, es mit PLINQ interagieren zu lassen. Mir ist allerdings aufgefallen, dass die beiden Code-mäßig nicht sehr schön zusammenspielen. In der Tat ist es nicht möglich sein, Code zu schreiben, wie die folgenden:F # und PLINQ Erweiterungsmethoden


open System.Linq 
let someArray = [|"abc"; "def"|] 
someArray.AsParallel().Count(new Func<_,_>(fun s -> s.Length = 3)) 

weil die Erweiterungsmethoden für ParallelQuery in der System.Linq.ParallelEnumerable Klasse enthalten ist offenbar nicht von F # zu abgeholt.
Ich wäre nicht überrascht, wenn überhaupt keine Unterstützung für Erweiterungsmethoden wäre, aber da ich auf die für IEnumerable definierte Erweiterungsmethode someArray.Count zugreifen kann, frage ich mich, warum ich nicht auf die von PLINQ zugreifen kann.
Fehle ich etwas?
Ist dies eine F # -Begrenzung? Wenn ja, ist das Design? Wenn nicht, wird es in einer zukünftigen Version angesprochen werden?

Antwort

3

Wenn Sie noch nicht .NET 4.0 verwenden, können Sie schreiben, dass als:

#r "System.Threading" 
open System.Linq 

let someArray = [|"abc"; "def"|] 

someArray.AsParallel<string>() 
|> Seq.filter (fun s -> s.Length = 3) 
|> Seq.length 

4,0 .NET kommen, können Sie einfach schreiben:

let someArray = [|"abc"; "def"|] 

someArray 
|> Array.Parallel.filter (fun s -> s.Length = 3) 
|> Array.length 

F # bevorzugt die Verwendung von das Seq-Modul über Linq-Erweiterungsmethoden. In der FSharp.PowerPack.Linq-Assembly sind jedoch einige Hilfsfunktionen verfügbar.

+0

Obwohl man nicht wählen kann, weil seine Signatur ist ('T ->' U-Option) -> 'T-Array ->' U-Array haben Sie mir die Lösung: Geben Sie den Typ in AsParallel. Tatsächlich sieht es so aus, als würde die nicht-generische Version zurückgegeben. Schließlich weiß ich, dass Seq, Array und andere Module in F # bevorzugt sind, aber unter verschiedenen Umständen könnte man eher mit etwas anfangen, das kein Array ist, oder etwas wollen, das Array.Parallel nicht bietet. – em70

+0

Mein schlechtes, das wird nicht tun. Während nach der Verwendung von AsParallel die Erweiterungsmethoden abgeholt werden, kann der Compiler die richtige Überladung nicht auflösen, so dass es nutzlos ist :( – em70

+0

Ich entschuldige mich für den Array.choose Fehler.Ich habe das kurz nachdem ich gepostet habe entdeckt, aber du hast es gefunden, bevor ich es auf die korrekte Version bearbeitet habe. ;) FYI-in F #, das Seq-Modul beschäftigt sich mit jedem IEnumerable und der Seq-Typ ist synonym mit IEnumerable. –

1

Wenn ich mich richtig erinnere, ist PLINQ auf der To-Do-Liste des Entwicklungsteams bei Microsoft, obwohl ich nicht sicher bin, dass es in .NET 4.0 erscheint. F # hat jedoch Asynchronous Workflows, was PLINQ sehr ähnlich ist (außer dass es sich um List-Comprehensions handelt, was die Standardfunktionalität ist). Ich kann den Artikel nicht finden, der bessere Unterstützung in F # für die parallelen Erweiterungen (PLINQ/TPL) erwähnt, also zitiere mich nicht darauf, aber ich bin mir ziemlich sicher, dass ich es irgendwo gesehen habe.

Abgesehen von der MSDN-Seite scheint this article eine gute Einführung in das Thema zu sein.

Es gibt auch this blog series (Mit PLINQ in F #), die nützlich sein könnten zu lesen, wenn Sie immer noch lieber PLINQ über Async Workflows verwenden.

+0

ich über asynchrone Workflows wissen aber in einigen Fällen sind sie ganz bestimmt nicht so handlich als PLINQ. Würden Sie mir bitte auch die Quelle mitteilen, dass PLINQ + F # im Zeitplan liegt? Schließlich, warum Erweiterungen in einem Fall funktionieren (IEnumerable ) und brechen Sie einen anderen? – em70

+0

Ja, ich stimme zu, dass PLINQ in einigen Situationen mehr Spielraum und Funktionalität bietet. Beitrag ist aktualisiert. – Noldorin

1

Erweiterungsmethoden sind nur Statik, die das Objekt als ersten Parameter nehmen, so sollten Sie es nennen können, mit

ParallelEnumerable.AsParallel(someArray).Count(...)