Programování

14 vynikajících důvodů pro použití F #

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 nulanebo 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é sa 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
$config[zx-auto] not found$config[zx-overlay] not found