F # je silně typizovaný programovací jazyk s první funkcí, který vám umožní vyřešit složité problémy napsáním jednoduchého kódu. F # vychází z ML a je postaven na .NET Framework a nabízí dobrou interoperabilitu, přenositelnost a rychlost běhu a také „pět C“ - přesnost, pohodlí, správnost, souběžnost a úplnost.
F # byl zpočátku k dispozici pouze pro Windows jako projekt Microsoft Research, ale nyní je to prvotřídní jazyk na řadě platforem. F # můžete použít pro Mac a Linux s podporou nástrojů v Xamarin Studio, MonoDevelop, Emacs a dalších; ve Windows s Visual Studio, Xamarin Studio a Emacs; a na zařízeních Android a iOS a na webu pomocí HTML5. Kromě programování pro obecné účely je F # použitelný pro kód GPU, velká data, hry a mnoho dalšího.
Proč používat F #? Dovolte mi uvést 14 důvodů.
F # je interaktivní
Jednou z výhod F # je, že má interaktivní REPL (čtení, vyhodnocení, tisk, smyčka), kde si můžete vyzkoušet kód, jak je znázorněno na obrázku níže. Ve směru hodinových ručiček, z levého horního rohu, vidíme interaktivní okna F # ze sady Visual Studio ve Windows, z TryFSharpu spuštěného v Chromu a ze Xamarin Studio běžícího na Mac OS X. ;;
řekne F # Interactive, aby vyhodnotila, co jste zadali; na TryFSharpu vysílá tlačítko „běh“ stejný signál. Použití REPL ke kompilaci a testování kódu před tím, než přejde do úplného programu, jak urychluje vývoj, tak snižuje chyby.
F # je pro skriptování
F # lze použít jako skriptovací jazyk i programovací jazyk. Níže vidíme ukázku sady Visual Studio, ve které skript F # načte čtyři soubory programu F # a před spuštěním vlastního kódu otevře dvě knihovny .NET. Zápis [|…|]
zde použité deklaruje pole. Zápis |>
je přední trubka, která předává výsledek levé strany funkci na pravé straně. Nové řádky zde nejsou syntakticky významné. Prostě usnadňují čtení kódu než mít celé výrazy kanálu na jednom řádku.
F # je funkční
F # podporuje konstrukty funkčního programování, jako je zpracování funkcí jako hodnot, použití nepojmenovaných funkcí ve výrazech, složení funkcí k vytvoření nových funkcí, curriedové funkce a implicitní definice funkcí prostřednictvím částečné aplikace argumentů funkcí. V horním snímku obrazovky níže definujeme a používáme přidat
funkce. Tělo funkce je odsazeno (jako Python) a typy argumentů jsou z důvodu odvozeny jako celá čísla +
operátor. V dolním snímku obrazovky dodáváme anotaci typu za názvem argumentu pomocí dvojtečky a názvu typu, takže F # ví, že fráze
je tětiva
typ.
F # je stručné
Níže uvedený kód je algoritmus podobný Quicksortu implementovaný v F # (Scott Wlaschin). The rec
klíčové slovo označuje, že funkce je rekurzivní. The zápas..s
syntaxe je a přepínač
prohlášení o steroidech, s |
indikující případy. The []
označuje prázdný seznam. The prvníElem
a otherElements
jsou vytvářeny automaticky.
Všimněte si, že v kódu nejsou nikde zmíněny žádné deklarace typů, což znamená, že funkce může třídit seznamy obsahující jakýkoli typ, který podporuje operátory porovnání. The zábava
klíčové slovo slouží k definování anonymní funkce lambda.
nechť rec quicksort list =seznam zápasů s
| [] -> // Pokud je seznam prázdný
[] // vrací prázdný seznam
| firstElem :: otherElements -> // Pokud seznam není prázdný
nechte smallElements = // extrahovat ty menší
otherElements
|> List.filter (zábava e -> e <firstElem)
|> quicksort // a seřadit je
nechte větší prvky = // extrahujte ty velké
otherElements
|> List.filter (zábava e -> e> = firstElem)
|> quicksort // a seřadit je
// Zkombinujte 3 části do nového seznamu a vraťte je
List.concat [smallerElements; [firstElem]; largerElements]
//test
printfn "% A" (quicksort [1; 5; 23; 18; 9; 1; 3])
Pro srovnání se podívejte na tradiční implementaci C # níže.
veřejná třída QuickSortHelper{
veřejný statický seznam QuickSort (hodnoty seznamu)
kde T: srovnatelné
{
if (values.Count == 0)
{
vrátit nový List ();
}
// získá první prvek
T firstElement = hodnoty [0];
// získá menší a větší prvky
var smallerElements = new List ();
var largerElements = new List ();
for (int i = 1; i <values.Count; i ++) // i začíná na 1
{// ne 0!
var elem = hodnoty [i];
if (elem.CompareTo (firstElement) <0)
{
smallerElements.Add (elem);
}
jiný
{
largerElements.Add (elem);
}
}
// vrátí výsledek
var result = new List ();
result.AddRange (QuickSort (smallerElements.ToList ()));
result.Add (firstElement);
result.AddRange (QuickSort (largerElements.ToList ()));
vrátit výsledek;
}
}
Všimnete si, jak moc extra kód C # má oproti F # kódu.
F # je opravdu stručný
Podle Scotta Wlaschina má níže uvedená verze rychlého řazení - všechny jeho čtyři řádky - typický výstižný vzhled F # napsaný zkušeným funkčním kodérem. Samozřejmě by byl první, kdo by poukázal na to, že se neřídí na místě. Trvalo mi několikrát, než jsem pochopil kód, ale stálo to za čas.
let rec quicksort2 = funkce| [] -> []
| první :: odpočinek ->
nechat menší, větší = List.partition ((> =) first) rest
List.concat [quicksort2 menší; [První]; quicksort2 větší]
// testovací kód
printfn "% A" (quicksort2 [1; 5; 23; 18; 9; 1; 3])
Stručně řečeno, první případ vrátí prázdný seznam, pokud je splněn, s kritériem ukončení; druhý případ rozdělí seznam na první prvek a zbytek a přiřadí podseznam začínající menší hodnotou menší
a druhý podřízený seznam větší
. V rámci zřetězení sublistů funkce rekurzivně seřadí menší
a větší
seznamy.
F # snižuje chyby díky silnému psaní
Na rozdíl od JavaScriptu, Ruby a Pythonu je F # silně zadáván, ne dynamicky zadáván. Na rozdíl od C a C ++, které jsou také silně napsané, ale vyžadují deklaraci všech typů, F # provádí odvození typu, kdykoli je to možné. Když odvození typu není možné, ale typ je třeba znát, kompilátor F # vyvolá chybu a navrhne, abyste zadali anotaci typu, jak jsme to museli udělat v dřívějším příkladu pro (fráze: řetězec)
argument k toHackerTalk
funkce. Chytání neshody typů v době kompilace eliminuje celou třídu chyb za běhu, ke kterým jsou náchylné jazyky s dynamickým typem.
Mimochodem, F # nechat
vazby jsou neměnné, pokud je výslovně nevyhlásíte proměnlivý
.
F # má velkou, dobře zvolenou sadu objektů, včetně List, String a Array
Jak můžete vidět z níže uvedeného IntelliSense, F # má bohaté List, String a Array moduly založené na .NET Framework. V tomto ohledu je to také objektově orientovaný jazyk, i když je to především funkční jazyk. Všimněte si, že nezáleží na tom, zda použijete název modulu nebo zadaný název proměnné - když přidáte tečku, objeví se členské funkce. Někteří lidé tvrdí, že výslovné použití názvu modulu je pro funkční jazyk lepší styl než tečkované proměnné, ale tento argument si úplně nekoupím.
F # je užitečné pro MapReduce
MapReduce je efektivní dvoustupňový proces, který se často používá na velkých datech a je výslovně podporován v Hadoopu. V tomto příkladu F # mapujeme a zmenšujeme seznam celých čísel. Nejprve filtrujeme seznam na sudá čísla, potom každé číslo zdvojnásobíme a nakonec vezmeme součet všech prvků v seznamu, abychom agregovali nebo snížili výsledek. List.map
je výkonná funkce vyššího řádu; funkce vyššího řádu je ta, která bere jinou funkci jako argument. Kromě seznamů a polí podporuje F # záznamy, sekvence, poskytovatele datových typů a LINQ (dotaz integrovaný do jazyka).
F # má záznamy
Záznamy F # představují jednoduché agregáty pojmenovaných hodnot, volitelně s členy. V níže uvedeném příkladu nejdříve definujeme a Rezervovat
typ záznamu se čtyřmi pojmenovanými hodnotami a poté vytvoříme záznam se stejnými čtyřmi názvy. F # kompilátor správně odvodí Rezervovat
zadejte odpovídající jména.
Záznamy F # mohou mít volitelné hodnoty
Záznamy nemusí vždy obsahovat všechny jejich pojmenované hodnoty. Pokud zadáte pojmenovanou hodnotu, volba
atribut, když definujete typ, pak může být vynechán ze záznamu. Když nastavíte volitelnou hodnotu, může být buď Žádný
, který končí jako nula
nebo může být Nějaký
následuje hodnota, kterou chcete nastavit. Pole záznamu se liší od tříd v tom, že jsou automaticky vystavena jako vlastnosti. Třídy a struktury ve F # jsou třídy a struktury .NET, kompatibilní s C # a Visual Basic .NET, takže se vzdám příkladů.
F # má sekvence
Sekvence v F # je logická řada prvků všeho jednoho typu. Sekvence jsou obzvláště užitečné, když máte velkou, uspořádanou sbírku dat, ale nemusíte nutně očekávat, že použijete všechny prvky. Jednotlivé prvky sekvence se počítají pouze podle potřeby, takže sekvence může poskytnout lepší výkon než seznam v situacích, kdy se nepoužívají všechny prvky. The Sekv
modul poskytuje podporu pro manipulace zahrnující sekvence. Na obrázku níže demonstrujeme jednoduché sekvence, sekvence s výrazy a sekvence s filtry.
F # podporuje poskytovatele dat a LINQ
Níže používáme editor TryFSharp k otevření online meteorologické datové sady Freebase a dotazování poskytovatele dat na cyklóny, které zaznamenaly nejvyšší hodnoty větru. The dotaz {}
syntaxe implementuje LINQ pro F #. Použití této DLL je specifické pro TryFSharp. V aplikaci Visual Studio byste to udělali otevřete Microsoft.FSharp.Data.TypeProviders
a poté použijte příslušnou službu poskytovatele dat.
Výsledek:
[Hurikán Andrew; Hurikán Hugo; Hurikán Galveston 1900;
Tropická bouře Allison; Cyclone Tracy; Hurikán Iniki; Hurikán Ivan;
Cyklón Urísa z roku 1999; Hurikán Katrina; Typhoon Talim; Hurikán Rita;
Typhoon Herb; Hurikán Wilma; Typhoon Vera; 1962 tichomořská tajfunová sezóna;
Typhoon Ike; Typhoon Mireille; Typhoon Babe; Tropická bouře Arlene;
Hurikán Irene; Typhoon Zeb; Typhoon Maemi; Typhoon Bess; Typhoon Chanchu;
Typhoon Patsy; Typhoon Ewiniar; Hurikán Ioke; Typhoon Xangsane;…
F # může analyzovat data Hadoop
V tomto příkladu použijeme editor TryFsharp k otevření instance Hadoop Hive, která obsahuje mimo jiné datové sady měření prvků květu duhovky spolu s anotacemi měrných jednotek. V souladu s tím jsme povolili použití jednotkových anotací ve vlastnostech HiveTypeProvider
.
Tento výpočet vrací:
val avgPetalLength: float = 0,0374966443
F # porovnává vzory
F # zápas
výraz poskytuje řízení větvení, které je založeno na srovnání výrazu se sadou vzorů. Řádky 1-7 níže uvedeného příkladu definují rekurzivní isPalindrome
funkce. Řádky 8–10 definují funkci obálky pro isPalindrome
který ji volá poprvé pomocí celého řetězce. Protože „aba“ je palindrom, pak
klauzule řádku 9 vystřelí a vrátí se Některé s
a zápas
příkaz v řádku 11 generuje „Řetězec aba je palindrom“. The _ vzor
v řádku 14 je výchozí případ.
The zápas .. |
prohlášení ve F # má mnoho výhod oproti switch..case
příkaz v C #, C ++ a Java, nejdůležitější je, že způsobuje méně chyb.
F # podporuje asynchronní pracovní postupy
F # má přístup ke všem .NET Framework, ale má také vlastní syntaxi pro asynchronní pracovní postupy. The asynchronní {výraz}
syntaxe definuje neblokující výpočet. The dělat!
klíčové slovo provede asynchronní operaci a čeká na výsledek. The nechat!
klíčové slovo čeká na asynchronní operaci a přiřadí výsledek. A použití!
čeká na asynchronní operaci, přiřadí výsledek a uvolní prostředek. Async.RunSynchronously
provede asynchronní operaci a čeká na svůj výsledek. Chcete-li přidat paralelismus, použijte Async.Parallel
funkce, která přebírá seznam Async
objekty, nastaví kód pro každý z nich Async
objekt úlohy spustit paralelně a vrátí Async
objekt, který představuje paralelní výpočet. Pak dejte výsledek na Async.RunSynchronously
. (Níže uvedený příklad pochází z F # pro zábavu a zisk.)
F # zdroje
Další informace o F # naleznete na odkazech níže.
- Zkuste F #
- F # pro zábavu a zisk
- Referenční příručka jazyka F #
- Funkční programování v reálném světě
- F # knihy na Amazonu
- Bílá kniha F # 3
- Další odkazy