2016-08-14 4 views
5

Ich habe gerade angefangen, durch Buch ‚Tamizhvendan S Arbeits F # Applied und kam in diesem Code-Schnipsel:Welche Art von Typ ist das?

type WebPart = Context -> Async<Context option> 

Ich habe mich durch Microsofts F # docs sowie meine Lieblinge F # Website, Scott Wlaschin des F# for Fun and Profit aber Ich konnte keinen Hinweis auf diese Art von Typ finden. Es scheint nicht wie ein Datensatztyp. Es scheint fast wie eine einfache alte Funktion. Also, was ist es?

Danke für jede Hilfe Mädels und Jungs.

+3

Dies ist eine Abkürzung für eine Funktion. –

+0

Also nimmt in diesem Fall dieses 'WebPart' einen' Kontext' und umschließt einfach sowohl eine 'Option' als auch eine' Async' Berechnung um es herum? –

+0

Es könnte alles - es ist keine Funktionsdefinition - nur eine Bequemlichkeit für das Schreiben von Typ Anmerkungen. –

Antwort

12

Der Typ WebPart, den Sie suchen, kommt von Suave. Sie können mehr darüber unter https://suave.io/async.html lesen, aber ich fasse zusammen. Sie sind richtig: ist ein Typ für eine Funktion. Insbesondere ist es eine Funktion, die eine Context (die in Suave eine Kombination aus einem HTTP-Anforderungsdatensatz und einem Antwortdatensatz ist) und eine Context option asynchron zurückgibt. Das heißt, da einige Anforderungen fehlschlagen können, hat die Funktion die Option None anstelle eines Werts zurückzugeben. Und da einige Anfragen lange dauern können, werden alle Anfragen asynchron zurückgeliefert, daher die Async.

Um zwei Anfragen zusammenzufassen, stellt Suave den Bindeoperator >=> zur Verfügung, so dass Sie nicht ständig durch die Eingabe von async { match result1 with None -> None | Some x -> return! request2 x gehen müssen; Stattdessen können Sie einfach request1 >=> request2 für denselben Effekt eingeben.

Wenn Sie weitere Hilfe benötigen und die Suave-Dokumentation nicht durchlesen können, lassen Sie es uns wissen und wir werden versuchen, sie näher zu erläutern.

+1

Danke für die Hilfe! Was ich bis jetzt von Suave gesehen habe, war Scott Wlaschins Artikelserie * Railyway Oriented Programming * sehr ähnlich. –

+1

Gute Einsicht! Es ist in der Tat das gleiche Konzept wie ROP, da es einen "Erfolgs-" und einen "Fehler" -Pfad gibt, aber es gibt ein zusätzliches Async. Aber das ist das Schöne an der funktionalen Programmierung: Grundlegende Konzepte übertragen sich auf viele Situationen.Das "Bind" -Konzept von ROP gilt auch für Async genauso wie es für ROP-style 'Success' /' Failure' Typen gilt. Lerne ein Konzept und du kannst es überall anwenden. – rmunn

3

Dies ist zu lang, um ein Kommentar zu sein. Und ich habe Suave nie benutzt. Ich denke jedoch, dass ich aus den monadischen Eigenschaften der beteiligten Typen erraten kann, dass >=> kein Bindeoperator ist, sondern der kompositorische Operator von Kleisli. Ohne monad laws zu Beobachten oder versuchen category theory zu verstehen, nur durch die Unterschriften der Annahme zu sein:

val (>>=) : 
    Async<'a option> -> ('a -> Async<'b option>) -> Async<'b option> 
val (>=>) : 
    ('a -> Async<'b option>) -> ('b -> Async<'c option>) -> 'a -> Async<'c option> 

Der bind Operator nimmt eine Async<'a option> und wandelt sie durch eine Bindemittelfunktion 'a -> Async<'b option> in eine Async<'b option>. Der Kleisli-Operator setzt zwei Binderfunktionen zu einer dritten zusammen.

Diese Operatoren arbeiten an monadischen Typen und Funktionen, die allgemeiner sind als die konkreten Typen, die durch eine Typenabkürzung wie type WebPart = Context -> Async<Context option> beschrieben werden. Eine Implementierung der Operatoren folgt nahezu selbstverständlich.

let (>>=) request1 binder = async { 
    let! result1 = request1 
    match result1 with 
    | None -> return None 
    | Some x -> return! binder x } 

let (>=>) f g a = f a >>= g