Hlavní navigace

Datové typy Option, Result a Array v programovacím jazyku F#

10. 10. 2023
Doba čtení: 32 minut

Sdílet

 Autor: Depositphotos
V páté části seriálu o jazyku F# si popíšeme práci s dalšími velmi užitečnými datovými typy. V první řadě se jedná o typy Option a Result, které byly mj. použity, resp. přesněji řečeno převzaty i do jazyka Rust.

Obsah

1. Datové typy Option, Result a Array v programovacím jazyku F#

2. Datový typ Option

3. Definice datového typu Option

4. Vytvoření hodnoty typu Option

5. Přístup k uložené hodnotě: problematická a zcela neidiomatická varianta

6. Test, zda je hodnota naplněna či nikoli

7. Datový typ Option a pattern matching

8. Kontrola, zda jsou pokryty obě možnosti poskytované typem Option

9. Praktický příklad – hledání prvku v seznamu

10. Vylepšený výpis nalezeného či nenalezeného prvku

11. Datový typ Result

12. Praktický příklad – realizace funkce pro výpočet podílu dvou celočíselných hodnot

13. Vylepšený výpis podílu či chyby

14. Datový typ Array

15. Konstrukce pole: výčet prvků, opakování hodnoty v poli

16. Konstrukce pole s výpočtem hodnot jeho prvků

17. Modifikace (mutace) prvků pole

18. Repositář s demonstračními příklady

19. Literatura

20. Odkazy na Internetu

1. Datové typy Option, Result a Array v programovacím jazyku F#

V páté části seriálu o programovacím jazyku F# si popíšeme a na několika demonstračních příkladech ukážeme způsoby práce s dalšími v praxi mnohdy velmi užitečnými datovými typy, které lze nalézt v prakticky každém zdrojovém kódu napsaném v F#. V první řadě se jedná o datový typ nazvaný Option a taktéž o datový typ pojmenovaný Result, což jsou v podstatě monády (nelekněte se) použité, resp. přesněji řečeno převzaté mj. i do programovacího jazyka Rust. A v závěrečné části dnešního článku si navíc popíšeme způsob práce s poli (Array), které se v mnoha ohledech liší od již popsaných seznamů (List) a taktéž se pochopitelně používají v odlišných oblastech.

2. Datový typ Option

V programovacím jazyku F# se poměrně často používá datový typ nazvaný Option, a to ve chvílích, kdy je zapotřebí reprezentovat neznámou hodnotu, chybějící hodnotu (ovšem bez vyvolání výjimky), vytvořit funkci s volitelnými parametry či vytvořit typově bezpečnou obdobu odkazu typu null. Dnes si ukážeme některé možnosti, které tento datový typ programátorům nabízí. Na tomto místě je vhodné doplnit, že podobný typ ovšem nalezneme i v mnoha dalších programovacích jazycích, viz například výše zmíněný jazyk Rust apod., popř. Haskell se svým typem nazvaným Maybe.

Poznámka: již na tomto místě je vhodné si uvědomit, že sémantika datového typu Option je odlišná od hodnoty null tak, jak je použita například v programovacím jazyku Java. Jak totiž uvidíme dále, nevede manipulace s hodnotami typu Option k vyhození slavné výjimky „NullPointerException“ (ani žádné její obdoby) z důvodu neošetření tohoto stavu. Naopak – díky sémantice Option, pattern matchingu a kontrolám překladače budou programy z tohoto hlediska bezpečné.

3. Definice datového typu Option

Samotná definice datového typu Option v jazyce F# vypadá následovně:

type Option<'a> =
   | Some of 'a
   | None

Vidíme, že se ve skutečnosti vlastně jedná o výčtový typ s pouhými dvěma explicitně zapsanými (a překladači známými) hodnotami None a Some, přičemž Some „obaluje“ vlastní hodnotu typu 'a (alfa), se kterou chceme pracovat. Současně se tedy – zcela podle očekávání – jedná o generický datový typ, což v praxi znamená, že volitelná hodnota může být jakéhokoli typu (ovšem samozřejmě hlídaného překladačem již v době překladu zdrojového kódu).

Poznámka: v programovacím jazyku F# navíc ještě nalezneme klíčové slovo option (začínající malým písmenem), které se při definici konkrétního uživatelského datového typu zapisuje na konec definice. I s tímto klíčovým slovem se setkáme v navazujících kapitolách.

Jen pro zajímavost se podívejme, jak je typ Option definovaný v Rustu:

enum Option<T> {
    None,
    Some(T),
}

až na rozdílnou syntaxi se tedy jedná o sémanticky prakticky totožný datový typ.

4. Vytvoření hodnoty typu Option

V praxi je důležitější vědět, jakým způsobem se vlastně vytvoří hodnota typu Option. Víme již, že se jedná o „obalový typ“, což znamená, že hodnota typu Option je buď rovna None nebo obaluje (wrap) konkrétní hodnotu. Konstrukce proměnné typu Option může vypadat následovně:

let maybeAnswer = Some 42

Povšimněte si, že překladač si správně odvodil, že se jedná o typ Option a obalenou hodnotou je celé číslo 42 (což bude dále využito při typových inferencích):

val maybeAnswer : int option = Some 42

Můžeme si samozřejmě nechat obalit například i hodnotu typu řetězec:

let maybeHello = Some "Hello world"

Výsledkem je proměnná tohoto typu:

val maybeHello : string option = Some "Hello world"

A konečně si ukažme použití „větve“ None:

let noAnswer = None

Proměnná, do níž přiřadíme hodnotu None, bude odlišného typu, než tomu bylo u předchozích proměnných:

val noAnswer : 'a option = None
Poznámka: vlastně se jedná o generiku, ovšem s jedinou hodnotou.

5. Přístup k uložené hodnotě: problematická a zcela neidiomatická varianta

K hodnotě, která je typem Option „obalena“, je možné přistoupit tak, že použijeme tečkovou notaci (tu jsme již viděli například u seznamů). Celý zápis by mohl vypadat následovně:

let maybeAnswer = Some 42
printf "%d" maybeAnswer.Value

Tento zápis sice může vypadat jednoduše a pro programátory lákavě, ale má několik nectností a neměl by být v praxi používán, pokud existuje alternativní varianta (a ta prakticky vždycky existuje). Problém spočívá v tom, že výpočet bude korektní jen tehdy, pokud proměnná maybeAnswer obsahuje hodnotu Some(typ). V případě, že obsahuje hodnotu None (což pochopitelně může – proč bychom jinak Option vůbec používali), může dojít k vyhození výjimky typu System.NullReferenceException.

6. Test, zda je hodnota naplněna či nikoli

S přístupem k obalované hodnotě přes proměnná.Value do značné míry souvisí i atributy (přesněji řečeno predikáty zapisované jako atributy), které nám umožní otestovat, zda pracujeme s hodnotou Some(typ) nebo None. Tyto atributy se jmenují IsNone a IsSome a vždy jeden z nich obsahuje hodnotu true a druhý (logicky) hodnotu false. Jejich použití je snadné (a typicky neidiomatické!).

Pro hodnotu None:

let maybeAnswer = None
 
printf "IsNone: %b" maybeAnswer.IsNone
printf "IsSome: %b" maybeAnswer.IsSome

Výsledky:

IsNone: true
IsSome: false

A pro libovolnou hodnotu Some(typ):

let maybeAnswer = Some 42
 
printf "IsNone: %b" maybeAnswer.IsNone
printf "IsSome: %b" maybeAnswer.IsSome

Výsledky:

IsNone: false
IsSome: true

7. Datový typ Option a pattern matching

Velká síla a elegance programovacího jazyka F# spočívá v tom, jak dokáže s datovým typem Option pracovat s využitím pattern matchingu. Ten nám totiž umožňuje velmi elegantním způsobem hodnoty typu Option(typ) zpracovávat. Podívejme se na jednoduchý příklad, v němž je implementována funkce, která zjistí, zda jí předáváme None či obalenou hodnotu. Ze zápisu je zřejmé, jak se pattern matching používá a jak vlastně obalenou hodnotu dokážeme získat:

let exists x =
    match x with
    | Some(x) -> true
    | None -> false
 
let maybeAnswer1 = Some 42
let maybeAnswer2 = None
 
printf "%b" (exists maybeAnswer1)
printf "%b" (exists maybeAnswer2)

Výsledkem bude dvojice zpráv:

true
false

8. Kontrola, zda jsou pokryty obě možnosti poskytované typem Option

Díky tomu, že překladač ví, jak přesně je definován typ Option, dokáže detekovat takový programový kód, v němž nejsou pokryty všechny možnosti, které mohou v runtime nastat. Podívejme se například na funkci, v níž jsme „omylem“ vynechali vzor None s jeho větví:

let exists x =
    match x with
    | Some(x) -> true

Překladač v tomto případě vypíše varování, které není vhodné ignorovat:

Incomplete pattern matches on this expression. For example, the value 'None'
may indicate a case not covered by the pattern(s).

Pokusme se naopak vynechat vzor Some s jeho větví:

let exists x =
    match x with
    | None -> false

Překladač opět vypíše varování, které bude tentokrát odlišné, ale opět poměrně přesně ukazuje na chybu, ke které došlo:

Incomplete pattern matches on this expression. For example, the value 'Some(_)' may indicate a case not covered by the pattern(s).

9. Praktický příklad – hledání prvku v seznamu

Podívejme se nyní na praktický příklad použití datového typu Option společně s pattern matchingem. Budeme implementovat funkci pro vyhledání prvku s nějakou hodnotou v seznamu. V případě, že prvek bude nalezen, vrátí se jeho hodnota obalená do Some(typ), pokud nalezen nebude, vrátí se hodnota None (nemusíme tedy řešit nějaké „magické hodnoty“ pro signalizaci, že prvek nebyl nalezen). Typ prvků bude odvozen překladačem – a asi není překvapením, že se bude v tomto konkrétním případě jednat o int. Implementace rekurzivního průchodu seznamem s vyhledáváním prvku může vypadat následovně:

let rec find list value =
    match list with
    | head :: tail -> if head = value then Some(head) else find tail value
    | [] -> None
 
let list1 = [1; 2; 3; 4]
let list2 = [0; 0; 0; 0]
let list3 = []
let list4 = [3]
 
printf "%A" (find list1 3)
printf "%A" (find list2 3)
printf "%A" (find list3 3)
printf "%A" (find list4 3)

Výsledky:

3
null
null
3

10. Vylepšený výpis nalezeného či nenalezeného prvku

Demonstrační příklad z předchozí kapitoly měl nevýhodu v tom, že se hodnota nalezeného či naopak nenalezeného prvku vypisovala přímo funkcí printf s formátovacím řetězcem „%A“ (any), což vedlo k výpisu poněkud matoucí zprávy null v případě, že prvek nalezen nebyl. Výhodnější možná bude, když se o realizaci výpisu postaráme sami. Není to nic těžkého, protože opět použijeme pattern matching:

let print_item value =
    match value with
    | Some(x) -> printf "%d" x
    | None -> printf "not found"
Poznámka: povšimněte si, že tato funkce nevrací žádnou hodnotu, pouze má vedlejší efekt (vypisuje zprávu na terminál).

Původní demonstrační příklad tedy upravíme do následující podoby:

let rec find list value =
    match list with
    | head :: tail -> if head = value then Some(head) else find tail value
    | [] -> None
 
let print_item value =
    match value with
    | Some(x) -> printf "%d" x
    | None -> printf "not found"
 
let list1 = [1; 2; 3; 4]
let list2 = [0; 0; 0; 0]
let list3 = []
let list4 = [3]
 
print_item (find list1 3)
print_item (find list2 3)
print_item (find list3 3)
print_item (find list4 3)

Nyní by měly být vypsané výsledky lépe pochopitelné (resp. přesněji řečeno méně matoucí):

3
not found
not found
3

11. Datový typ Result

V mnoha případech však nemusí být použití datového typu Option tím nejlepším řešením. Pro příklad nemusíme chodit daleko – předpokládejme, že budeme chtít, aby námi definovaná funkce pro dělení celých čísel vracela v případě pokusu o dělení nulou chybové hlášení a nikoli nicneříkající hodnotu None. K tomuto účelu se v programovacím jazyku F# používá datový typ nazvaný příhodně Result. Tento datový typ se podobá již popsanému typu Option, ovšem s tím rozdílem, že obaluje buď výsledek (třeba návratovou hodnotu volané funkce) nebo informaci o chybě. Deklarace struktury Result vypadá následovně:

type Result<'T,'TError> =
    | Ok of ResultValue:'T
    | Error of ErrorValue:'TError

Jen pro zajímavost a doplnění se podívejme, jak je tomu v Rustu:

enum Result<T, E> {
    Ok(T),
    Err(E),
}
Poznámka: opět tedy platí, že rozdíl je především v syntaxi, nikoli v sémantice.

12. Praktický příklad – realizace funkce pro výpočet podílu dvou celočíselných hodnot

Podívejme se nyní na velmi jednoduchý demonstrační příklad, na němž si ukážeme způsob použití datového typu Result. V tomto příkladu je realizována funkce pro výpočet podílu dvou celočíselných hodnot. Pokud nedojde k dělení nulou, vrátí se vypočtený výsledek „obalený“ do Ok. V opačném případě se vrátí informace o chybě zapsaná v Error.

let divide (x:int) (y:int) =
    match y with
    | 0 -> Error "divide by zero"
    | _ -> Ok (x/y)
 
printf "%A\n" (divide 10 2)
printf "%A\n" (divide 10 0)

Po spuštění získáme tyto dvě zprávy:

Ok 5
Error divide by zero
Poznámka: ve skutečnosti nemusíme explicitně zapisovat typ parametrů a příklad lze tedy zkrátit na:
let divide x y =
    match y with
    | 0 -> Error "divide by zero"
    | _ -> Ok (x/y)
 
printf "%A\n" (divide 10 2)
printf "%A\n" (divide 10 0)

13. Vylepšený výpis podílu či chyby

Pro získání výsledku zabaleného do Ok nebo naopak informace o chybě zabalené do Error pochopitelně opět můžeme využít pattern matching, podobně jako v případě typu Option (kde nás ovšem zajímalo rozbalení hodnoty ze Some). Do předchozího demonstračního příkladu tedy například můžeme přidat funkci, která vypíše výsledek, popř. fakt, že došlo k dělení nulou:

let print_result value =
    match value with
    | Ok(x) -> printf "%d" x
    | Error(x) -> printf "hmm, dělení nulou"

Celý příklad bude vypadat následovně:

let divide (x:int) (y:int) =
    match y with
    | 0 -> Error "divide by zero"
    | _ -> Ok (x/y)
 
let print_result value =
    match value with
    | Ok(x) -> printf "%d" x
    | Error(x) -> printf "hmm, dělení nulou"
 
print_result (divide 10 2)
print_result (divide 1 0)

A po jeho spuštění získáme dvojici zpráv:

5
hmm, dělení nulou

14. Datový typ Array

Posledním datovým typem, s nímž se v dnešním článku seznámíme, je typ Array neboli pole. Podobně jako u seznamů, i u pole platí, že se jedná o homogenní datový typ, což znamená, že všechny jeho prvky jsou stejného typu. Přístup k prvkům se uskutečňuje přes indexy tak, jak jsme na to zvyklí z dalších programovacích jazyků.

Pole sice mohou na první pohled vypadat podobně jako seznamy, ovšem jejich vlastnosti se v mnoha ohledech odlišují. Zásadním rozdílem je, že prvky pole je možné měnit (takže pole je jako celek měnitelné – mutable), kdežto seznamy jsou neměnitelné. Ovšem odlišné jsou i další vlastnosti, například složitosti některých operací, které je možné s oběma datovými typy provádět. Ostatně se podívejme na následující tabulku, která oba tyto homogenní datové typy porovnává z hlediska časové složitosti jednotlivých operací:

Operace Seznam Pole
přidání prvku O(1) O(n)
přístup k prvku O(n) O(1)
modifikace prvku × O(1)
Poznámka: přidání prvku vrací nový seznam nebo nové pole (u seznamů se pro přidání prvku na začátek používá operátor ::).

Z rozdílných vlastností seznamů a polí plyne i to, v jakých oblastech se tyto datové typy uplatní. Seznamy se uplatní při operacích využívajících pattern matching (kde se typicky zpracovávají prvky postupně ve stylu hlava:ocas), ale nehodí se pro náhodný přístup k prvkům. Naproti tomu pole jsou ideálním kontejnerem ve chvíli, kdy je předem známý počet prvků, vyžaduje se náhodný přístup k prvkům a/nebo jejich modifikace.

15. Konstrukce pole: výčet prvků, opakování hodnoty v poli

Pole lze v jazyku F# zkonstruovat několika možnými způsoby. Základem je konstrukce založená na zápisu výčtu hodnot všech prvků, které mají být v poli uloženy. Tento zápis (syntaxe) vypadá následovně:

let a = [| 1; 2; 3; 4; |]
 
printf "%A" a
Poznámka: na rozdíl od seznamů tedy používáme „závorky“ [| a |], nikoli pouze [ a ]. Pro oddělení prvků se ovšem využívá stejný znak – středník.

Existují ovšem i další způsoby konstrukce pole. V balíčku Array nalezneme několik konstruktorů. Jedním z nich je i konstruktor nazvaný create. Tomu se předávají dva parametry: počet prvků konstruovaného pole a hodnota těchto prvků:

let a = Array.create 10 42
 
printf "%A" a

Výsledkem bude:

42,42,42,42,42,42,42,42,42,42

Samozřejmě můžeme zkonstruovat i pole odlišného typu:

let a = Array.create 5 "*"
 
printf "%A" a
Poznámka: pokud je vyžadováno pole s nulovými prvky, lze pro tento účel použít konstruktor nazvaný Array.zeroCreate. Ovšem v tomto případě je vhodné explicitně definovat typ proměnné, do které se pole ukládá:
let a:int[] = Array.zeroCreate 5
 
printf "%A" a

Pro přístup k prvkům pole se používá notace kombinující tečku+operátor indexování (toto je starší a kompatibilní způsob zápisu):

let a = [| 1; 2; 3; 4; |]
 
printf "%d" a.[0]
printf "%d" a.[1]
printf "%d" a.[-1]

V novějších verzích ovšem můžete použít lidštější zápis (který je navíc od šesté verze doporučován jako ten správný):

let a = [| 1; 2; 3; 4; |]
 
printf "%d" a[0]
printf "%d" a[1]
printf "%d" a[-1]

16. Konstrukce pole s výpočtem hodnot jeho prvků

Pole lze ovšem zkonstruovat i mnoha dalšími způsoby. Poměrně elegantním řešením může být použití funkce/konstruktoru Array.init, které se předává počet prvků pole a taktéž funkce, která je použita pro výpočet hodnoty n-tého prvku na základě indexu n. Můžeme si tak snadno vytvořit například aritmetickou posloupnost od 1 do n (tj.k indexu prvku přičteme jedničku):

let item_x x =
  x+1
 
let a = Array.init 10 item_x
 
printf "%A" a

Podobně ovšem můžeme vytvořit pole o deseti prvcích obsahujících sudá čísla:

let item_x x =
  x*2
 
let a = Array.init 10 item_x
 
printf "%A" a

17. Modifikace (mutace) prvků pole

Důležitou vlastností polí (kterou se navíc pole odlišují od seznamů) je fakt, že prvky pole je možné modifikovat neboli mutovat. K tomuto účelu slouží operátor ← , který již známe:

ict ve školství 24

let a = [| 1; 2; 3; 4; |];;
printf "%A" a
 
a.[0] <- 42;;
printf "%A" a
 
a.[1] <- 6502;;
printf "%A" a

Opět platí, že v novějších variantách jazyka F# lze psát:

let a = [| 1; 2; 3; 4; |];;
printf "%A" a
 
a[0] <- 42;;
printf "%A" a
 
a[1] <- 6502;;
printf "%A" a

18. Repositář s demonstračními příklady

Všechny výše popsané demonstrační příklady byly uloženy do repositáře dostupného na adrese https://github.com/tisnik/f-sharp-examples/. V tabulce umístěné pod tímto odstavcem jsou uvedeny odkazy na tyto příklady:

# Příklad Popis příkladu Cesta
1 ML/fib_recursive.ml výpočet hodnoty z Fibonacciho posloupnosti rekurzivně https://github.com/tisnik/f-sharp-examples/tree/master/ML/fib_re­cursive.ml
2 ML/fib_pattern_matching.ml výpočet hodnoty z Fibonacciho posloupnosti založený na pattern matchingu https://github.com/tisnik/f-sharp-examples/tree/master/ML/fib_pat­tern_matching.ml
3 ML/len_pattern_matching1.ml výpočet délky seznamu založený na pattern matchingu (první varianta) https://github.com/tisnik/f-sharp-examples/tree/master/ML/len_pat­tern_matching1.ml
4 ML/len_pattern_matching2.ml výpočet délky seznamu založený na pattern matchingu (zkrácená varianta) https://github.com/tisnik/f-sharp-examples/tree/master/ML/len_pat­tern_matching2.ml
       
5 OCaml/fib_recursive.ml výpočet hodnoty z Fibonacciho posloupnosti rekurzivně https://github.com/tisnik/f-sharp-examples/tree/master/OCam­l/fib_recursive.ml
6 OCaml/fib_tail_recursive.ml výpočet hodnoty z Fibonacciho posloupnosti s využitím koncové rekurze https://github.com/tisnik/f-sharp-examples/tree/master/OCam­l/fib_tail_recursive.ml
7 OCaml/fib_pattern_matching.ml výpočet hodnoty z Fibonacciho posloupnosti založený na pattern matchingu https://github.com/tisnik/f-sharp-examples/tree/master/OCam­l/fib_pattern_matching.ml
8 OCaml/local_binding.ml symbol lokální uvnitř funkce https://github.com/tisnik/f-sharp-examples/tree/master/OCam­l/local_binding.ml
       
9 article01/function.fs deklarace pojmenované funkce https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle01/function.fs
10 article01/lambda.fs deklarace anonymní funkce https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle01/lambda.fs
11 article01/local_binding1.fs lokální symboly ve funkci https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle01/local_binding1.fs
12 article01/local_binding2.fs lokální symboly ve funkci https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle01/local_binding2.fs
13 article01/function_type1.fs explicitní definice návratového typu funkce (korektní) https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle01/function_type1.fs
14 article01/function_type2.fs explicitní definice návratového typu funkce (nekorektní) https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle01/function_type2.fs
       
15 article02/basic_binding.fs navázání hodnoty na symbol (deklarace proměnné) https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/basic_binding.fs
16 article02/print_variable.fs tisk hodnoty proměnné https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/print_variable.fs
17 article02/variables_and_functions.fs předání proměnné do funkce https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/variables_and_functi­ons.fs
18 article02/redefine_symbol1.fs pokus o redefinici symbolu https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/redefine_symbol1.fs
19 article02/redefine_symbol2.fs pokus o redefinici symbolu (složitější příklad) https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/redefine_symbol2.fs
       
20 article02/equal_operator1.fs operátor = https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/equal_operator1.fs
21 article02/equal_operator2.fs operátor = https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/equal_operator2.fs
       
22 article02/immutable_variable.fs „změna“ neměnitelné proměnné https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/immutable_variable.fs
23 article02/mutable_variable.fs změna měnitelné proměnné https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/mutable_variable.fs
24 article02/reference1.fs reference, příklad kompatibilní s OCamlem https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/reference1.fs
25 article02/reference2.fs reference, nová syntaxe pro F# https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/reference2.fs
26 article02/incr1.fs standardní funkce incr https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/incr1.fs
27 article02/incr2.fs zvýšení referencované hodnoty o jedničku https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/incr2.fs
28 article02/shadow.fs shadowing symbolu https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/shadow.fs
       
29 article02/tuple.fs datový typ n-tice (tuple) https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/tuple.fs
30 article02/record1.fs datový typ záznam (record), deklarace proměnné tohoto typu https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/record1.fs
31 article02/record2.fs datový typ záznam (record) a typová inference při deklaraci proměnné https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/record2.fs
       
32 article02/basic_binding.fsx demonstrační příklad basic_binding.fs přepsaný do podoby skriptu pro dotnet fsi https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/basic_binding.fsx
33 article02/equal_operator1.fsx demonstrační příklad equal_operator1.fs přepsaný do podoby skriptu pro dotnet fsi https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/equal_operator1.fsx
34 article02/equal_operator2.fsx demonstrační příklad equal_operator2.fs přepsaný do podoby skriptu pro dotnet fsi https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/equal_operator2.fsx
35 article02/immutable_variable.fsx demonstrační příklad immutable_variable.fs přepsaný do podoby skriptu pro dotnet fsi https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/immutable_variable.fsx
36 article02/mutable_variable.fsx demonstrační příklad mutable_variable.fs přepsaný do podoby skriptu pro dotnet fsi https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/mutable_variable.fsx
37 article02/print_variable.fsx demonstrační příklad print_variable.fs přepsaný do podoby skriptu pro dotnet fsi https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/print_variable.fsx
38 article02/redefine_symbol1.fsx demonstrační příklad redefine_symbol1.fs přepsaný do podoby skriptu pro dotnet fsi https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/redefine_symbol1.fsx
39 article02/redefine_symbol2.fsx demonstrační příklad redefine_symbol2.fs přepsaný do podoby skriptu pro dotnet fsi https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/redefine_symbol2.fsx
40 article02/variables_and_functions.fsx demonstrační příklad variables_and_functions.fs přepsaný do podoby skriptu pro dotnet fsi https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/variables_and_functi­ons.fsx
41 article02/incr1.fsx demonstrační příklad incr1.fs přepsaný do podoby skriptu pro dotnet fsi https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/incr1.fsx
42 article02/incr2.fsx demonstrační příklad incr2.fs přepsaný do podoby skriptu pro dotnet fsi https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/incr2.fsx
43 article02/reference1.fsx demonstrační příklad reference1.fs přepsaný do podoby skriptu pro dotnet fsi https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/reference1.fsx
44 article02/reference2.fsx demonstrační příklad reference2.fs přepsaný do podoby skriptu pro dotnet fsi https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/reference2.fsx
45 article02/ident.fsx demonstrační příklad ident.fs přepsaný do podoby skriptu pro dotnet fsi https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle02/ident.fsx
       
46 article03/recursion1.fs pokus o deklaraci funkce s přímou rekurzí založený na let https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle03/recursion1.fs
47 article03/recursion2.fs deklarace funkce s přímou rekurzí založená na let rec https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle03/recursion2.fs
48 article03/recursion3.fs využití tail rekurze pro výpočet členu Fibonacciho posloupnosti https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle03/recursion3.fs
49 article03/recursion4.fs obyčejná nerekurzivní funkce definovaná přes let rec https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle03/recursion4.fs
       
50 article03/odd_even1.fs nepřímá rekurze (nekorektní varianta) https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle03/odd_even1.fs
51 article03/odd_even2.fs nepřímá rekurze (taktéž nekorektní varianta) https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle03/odd_even2.fs
52 article03/odd_even3.fs jediný korektní zápis nepřímé rekurze https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle03/odd_even3.fs
53 article03/odd_even4.fs nepřímá rekurze bez použití klíčového slova rec https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle03/odd_even4.fs
       
54 article03/pattern1.fs výpočet Faktoriálu založený na pattern matchingu https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle03/pattern1.fs
55 article03/pattern2.fs výpočet Faktoriálu založený na pattern matchingu, sloučení vstupů se stejným výstupem https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle03/pattern2.fs
56 article03/pattern3.fs kontrola neplatného vstupu https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle03/pattern3.fs
57 article03/pattern4.fs pattern matching pro větší množství hodnot https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle03/pattern4.fs
58 article03/pattern5.fs rekurzivní implementace Ackermannovy funkce https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle03/pattern5.fs
59 article03/pattern6.fs kontrola neplatných vstupních hodnot pro Ackermannovu funkci https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle03/pattern6.fs
       
60 article03/fibonacci1.fs výpočet Fibonacciho posloupnosti založený na pattern matchingu https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle03/fibonacci1.fs
61 article03/fibonacci2.fs výpočet Fibonacciho posloupnosti založený na pattern matchingu (více idiomatický zápis) https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle03/fibonacci2.fs
       
62 article03/first.fs funkce vracející první prvek z dvojice založená na pattern matchingu https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle03/first.fs
63 article03/second.fs funkce vracející druhý prvek z dvojice založená na pattern matchingu https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle03/second.fs
64 article03/zero_coordinate.fs test na nulovou souřadnici/souřadnice založený na pattern matchingu https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle03/zero_coordinate.fs
       
65 article03/get_model.fs získání prvku ze záznamu (opět založeno na pattern matchingu) https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle03/get_model.fs
       
66 article04/list_literal1.fs seznam se třemi prvky typu celé číslo https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle04/list_literal1.fs
67 article04/list_literal2.fs seznam se třemi prvky typu řetězec https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle04/list_literal2.fs
68 article04/list_literal3.fs seznam se třemi prvky typu n-tice https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle04/list_literal3.fs
69 article04/list_literal4.fs nekorektní pokus o vytvoření seznamu s prvky různých typů https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle04/list_literal4.fs
70 article04/empty_list.fs konstrukce prázdného seznamu https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle04/empty_list.fs
       
71 article04/head_tail1.fs složení seznamu se dvěma prvky s využitím operátoru :: https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle04/head_tail1.fs
72 article04/head_tail2.fs složení seznamu se třemi prvky s využitím operátoru :: https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle04/head_tail2.fs
       
73 article04/list_properties.fs vlastnosti (properties) seznamů https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle04/list_properties.fs
74 article04/len1.fs naivní rekurzivní výpočet délky seznamu https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle04/len1.fs
75 article04/len2.fs vylepšený rekurzivní výpočet délky seznamu https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle04/len2.fs
76 article04/len3.fs vylepšený rekurzivní výpočet délky seznamu https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle04/len3.fs
       
77 article04/range1.fs vytvoření sekvence numerických hodnot s využitím operátoru range https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle04/range1.fs
78 article04/range2.fs vytvoření sekvence numerických hodnot s využitím operátoru range https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle04/range2.fs
79 article04/range3.fs vytvoření sekvence numerických hodnot s využitím operátoru range https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle04/range3.fs
80 article04/range4.fs vytvoření sekvence numerických hodnot s využitím operátoru range https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle04/range4.fs
       
81 article04/join_lists.fs spojení dvou seznamů operátorem :: https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle04/join_lists.fs
82 article04/append1.fs implementace spojení dvou seznamů rekurzivním výpočtem https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle04/append1.fs
83 article04/append2.fs implementace spojení dvou seznamů rekurzivním výpočtem, použití pattern matchingu https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle04/append2.fs
       
84 article04/sum1.fs součet hodnot všech prvků v seznamu (bez tail rekurze) https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle04/sum1.fs
85 article04/sum2.fs součet hodnot všech prvků v seznamu (s využitím tail rekurze) https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle04/sum2.fs
       
86 article05/option_type.fs definice datového typu Option https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle05/option_type.fs
87 article05/none_value.fs hodnota None https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle05/none_value.fs
88 article05/some_value1.fs hodnota Some(typ) https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle05/some_value1.fs
89 article05/some_value2.fs hodnota Some(typ) https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle05/some_value2.fs
90 article05/option_value.fs přístup k zapouzdřené hodnotě přes Option.Value https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle05/option_value.fs
91 article05/is_none_is_some1.fs detekce, zda je hodnota Option rovna None či Some https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle05/is_none_is_some1.fs
92 article05/is_none_is_some2.fs detekce, zda je hodnota Option rovna None či Some https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle05/is_none_is_some2.fs
93 article05/option_exists1.fs základní pattern matching, korektní varianta https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle05/option_exists1.fs
94 article05/option_exists2.fs základní pattern matching, nekorektní varianta https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle05/option_exists2.fs
95 article05/option_exists3.fs základní pattern matching, nekorektní varianta https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle05/option_exists3.fs
96 article05/find_in_list1.fs vyhledávání prvku v seznamu založené na pattern matchingu https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle05/find_in_list1.fs
97 article05/find_in_list2.fs varianta předchozího programu https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle05/find_in_list2.fs
       
98 article05/result_type.fs definice datového typu Result https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle05/result_type.fs
99 article05/result_divide1.fs ukázka použití datového typu Result https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle05/result_divide1.fs
100 article05/result_divide2.fs ukázka použití datového typu Result a pattern matchingu https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle05/result_divide2.fs
101 article05/result_divide3.fs stejné jako result_divide1.fs, ovšem bez explicitního zápisu typů https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle05/result_divide3.fs
102 article05/result_divide4.fs stejné jako result_divide2.fs, ovšem bez explicitního zápisu typů https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle05/result_divide4.fs
       
103 article05/array_value.fs deklarace pole výčtem jeho prvků https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle05/array_value.fs
104 article05/array_create.fs funkce Array.create pro konstrukci pole https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle05/array_create.fs
105 article05/array_init1.fs inicializace prvků pole funkcí Array.init https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle05/array_init1.fs
106 article05/array_init2.fs inicializace prvků pole funkcí Array.init https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle05/array_init2.fs
107 article05/array_indexing.fs indexování prvků pole https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle05/array_indexing.fs
108 article05/array_mutation.fs mutace pole: modifikace hodnot jeho prvků https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle05/array_mutation.fs
109 article05/array_zerocreate.fs konstrukce pole s nulovými prvky https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle05/array_zerocreate.fs

19. Literatura

Poznámka: v této kapitole jsou uvedeny knihy o jazyku ML resp. Standard ML i knihy o programovacím jazyku OCaml, který ze Standard ML ze značné míry vychází. A samozřejmě nezapomeneme ani na knihy o jazyku F#:
  1. Get Programming with F#
    https://www.manning.com/books/get-programming-with-f-sharp
  2. F# for Scientists
    https://www.amazon.com/F-Scientists-Jon-Harrop-ebook/dp/B005PS97RO
  3. Domain Modeling Made Functional
    https://fsharpforfunandpro­fit.com/books/
  4. Functional Programming with F# (na Overleaf, tedy i se zdrojovými kódy)
    https://www.overleaf.com/pro­ject/5bf2cb3cd9568d5a75bfcb­a9
  5. Book of F#
    https://nostarch.com/fsharp
  6. F# Programming (Wikibook)
    https://en.wikibooks.org/wi­ki/F_Sharp_Programming
  7. Stylish F#: Crafting Elegant Functional Code for .NET and .NET Core
    https://www.amazon.com/dp/1484239997/
  8. ML for the Working Programmer
    https://www.cl.cam.ac.uk/~lp15/MLbo­ok/pub-details.html
  9. Elements of ML Programming, 2nd Edition (ML97)
    http://infolab.stanford.e­du/~ullman/emlp.html
  10. A tour of Standard ML
    https://saityi.github.io/sml-tour/tour/welcome
  11. The History of Standard ML
    https://smlfamily.github.i­o/history/SML-history.pdf
  12. The Standard ML Basis Library
    https://smlfamily.github.io/Basis/
  13. Programming in Standard ML
    http://www.cs.cmu.edu/~rwh/is­ml/book.pdf
  14. Programming in Standard ML '97: A Tutorial Introduction
    http://www.lfcs.inf.ed.ac­.uk/reports/97/ECS-LFCS-97–364/
  15. Programming in Standard ML '97: An On-line Tutorial
    https://homepages.inf.ed.ac­.uk/stg/NOTES/
  16. The OCaml system release 4.13
    https://ocaml.org/releases/4­.13/htmlman/index.html
  17. Real World OCaml: Functional programming for the masses
    https://dev.realworldocaml.org/
  18. OCaml from the Very Beginning
    http://ocaml-book.com/
  19. OCaml from the Very Beginning: More OCaml : Algorithms, Methods & Diversions
    http://ocaml-book.com/more-ocaml-algorithms-methods-diversions/
  20. Unix system programming in OCaml
    http://ocaml.github.io/ocamlunix/
  21. OCaml for Scientists
    https://www.ffconsultancy­.com/products/ocaml_for_sci­entists/index.html
  22. Using, Understanding, and Unraveling The OCaml Language
    https://caml.inria.fr/pub/docs/u3-ocaml/
  23. Developing Applications With objective Caml
    https://caml.inria.fr/pub/docs/oreilly-book/index.html
  24. Introduction to Objective Caml
    http://courses.cms.caltech­.edu/cs134/cs134b/book.pdf
  25. How to Think Like a (Functional) Programmer
    https://greenteapress.com/thin­kocaml/index.html

20. Odkazy na Internetu

  1. General-Purpose, Industrial-Strength, Expressive, and Safe
    https://ocaml.org/
  2. OCaml playground
    https://ocaml.org/play
  3. Online Ocaml Compiler IDE
    https://www.jdoodle.com/compile-ocaml-online/
  4. Get Started – OCaml
    https://www.ocaml.org/docs
  5. Get Up and Running With OCaml
    https://www.ocaml.org/docs/up-and-running
  6. Better OCaml (Online prostředí)
    https://betterocaml.ml/?ver­sion=4.14.0
  7. OCaml file extensions
    https://blog.waleedkhan.name/ocaml-file-extensions/
  8. First thoughts on Rust vs OCaml
    https://blog.darklang.com/first-thoughts-on-rust-vs-ocaml/
  9. Standard ML of New Jersey
    https://www.smlnj.org/
  10. Programming Languages: Standard ML – 1 (a navazující videa)
    https://www.youtube.com/wat­ch?v=2sqjUWGGzTo
  11. 6 Excellent Free Books to Learn Standard ML
    https://www.linuxlinks.com/excellent-free-books-learn-standard-ml/
  12. SOSML: The Online Interpreter for Standard ML
    https://sosml.org/
  13. ML (Computer program language)
    https://www.barnesandnoble­.com/b/books/other-programming-languages/ml-computer-program-language/_/N-29Z8q8Zvy7
  14. Strong Typing
    https://perl.plover.com/y­ak/typing/notes.html
  15. What to know before debating type systems
    http://blogs.perl.org/user­s/ovid/2010/08/what-to-know-before-debating-type-systems.html
  16. Types, and Why You Should Care (Youtube)
    https://www.youtube.com/wat­ch?v=0arFPIQatCU
  17. DynamicTyping (Martin Fowler)
    https://www.martinfowler.com/bli­ki/DynamicTyping.html
  18. DomainSpecificLanguage (Martin Fowler)
    https://www.martinfowler.com/bli­ki/DomainSpecificLanguage­.html
  19. Language Workbenches: The Killer-App for Domain Specific Languages?
    https://www.martinfowler.com/ar­ticles/languageWorkbench.html
  20. Effective ML (Youtube)
    https://www.youtube.com/watch?v=-J8YyfrSwTk
  21. Why OCaml (Youtube)
    https://www.youtube.com/wat­ch?v=v1CmGbOGb2I
  22. CSE 341: Functions and patterns
    https://courses.cs.washin­gton.edu/courses/cse341/04wi/lec­tures/03-ml-functions.html
  23. Comparing Objective Caml and Standard ML
    http://adam.chlipala.net/mlcomp/
  24. What are the key differences between Standard ML and OCaml?
    https://www.quora.com/What-are-the-key-differences-between-Standard-ML-and-OCaml?share=1
  25. Cheat Sheets (pro OCaml)
    https://www.ocaml.org/doc­s/cheat_sheets.html
  26. Syllabus (FAS CS51)
    https://cs51.io/college/syllabus/
  27. Abstraction and Design In Computation
    http://book.cs51.io/
  28. Learn X in Y minutes Where X=Standard ML
    https://learnxinyminutes.com/doc­s/standard-ml/
  29. CSE307 Online – Summer 2018: Principles of Programing Languages course
    https://www3.cs.stonybrook­.edu/~pfodor/courses/summer/cse307­.html
  30. CSE307 Principles of Programming Languages course: SML part 1
    https://www.youtube.com/wat­ch?v=p1n0_PsM6hw
  31. CSE 307 – Principles of Programming Languages – SML
    https://www3.cs.stonybrook­.edu/~pfodor/courses/summer/CSE307/L01_SML­.pdf
  32. SML, Some Basic Examples
    https://cs.fit.edu/~ryan/sml/in­tro.html
  33. History of programming languages
    https://devskiller.com/history-of-programming-languages/
  34. History of programming languages (Wikipedia)
    https://en.wikipedia.org/wi­ki/History_of_programming_lan­guages
  35. Jemný úvod do rozsáhlého světa jazyků LISP a Scheme
    https://www.root.cz/clanky/jemny-uvod-do-rozsahleho-sveta-jazyku-lisp-a-scheme/
  36. The Evolution Of Programming Languages
    https://www.i-programmer.info/news/98-languages/8809-the-evolution-of-programming-languages.html
  37. Evoluce programovacích jazyků
    https://ccrma.stanford.edu/cou­rses/250a-fall-2005/docs/ComputerLanguagesChart.png
  38. Poly/ML Homepage
    https://polyml.org/
  39. PolyConf 16: A brief history of F# / Rachel Reese
    https://www.youtube.com/wat­ch?v=cbDjpi727aY
  40. Programovací jazyk Clojure 18: základní techniky optimalizace aplikací
    https://www.root.cz/clanky/pro­gramovaci-jazyk-clojure-18-zakladni-techniky-optimalizace-aplikaci/
  41. Moscow ML Language Overview
    https://itu.dk/people/ses­toft/mosml/mosmlref.pdf
  42. ForLoops
    http://mlton.org/ForLoops
  43. Funkcionální dobrodružství v JavaScriptu
    https://blog.kolman.cz/2015/12/fun­kcionalni-dobrodruzstvi-v-javascriptu.html
  44. Recenze knihy Functional Thinking (Paradigm over syntax)
    https://www.root.cz/clanky/recenze-knihy-functional-thinking-paradigm-over-syntax/
  45. Currying
    https://sw-samuraj.cz/2011/02/currying/
  46. Používání funkcí v F#
    https://docs.microsoft.com/cs-cz/dotnet/fsharp/tutorials/using-functions
  47. Funkce vyššího řádu
    http://naucte-se.haskell.cz/funkce-vyssiho-radu
  48. Currying (Wikipedia)
    https://en.wikipedia.org/wi­ki/Currying
  49. Currying (Haskell wiki)
    https://wiki.haskell.org/Currying
  50. Haskell Curry
    https://en.wikipedia.org/wi­ki/Haskell_Curry
  51. Moses Schönfinkel
    https://en.wikipedia.org/wi­ki/Moses_Sch%C3%B6nfinkel
  52. .NET framework
    https://dotnet.microsoft.com/en-us/
  53. F# – .NET Blog
    https://devblogs.microsof­t.com/dotnet/category/fshar­p/
  54. Playground: OCaml
    https://ocaml.org/play
  55. The F# Survival Guide
    https://web.archive.org/web/20110715231625/htt­p://www.ctocorner.com/fshar­p/book/default.aspx
  56. Object-Oriented Programming — The Trillion Dollar Disaster
    https://betterprogramming.pub/object-oriented-programming-the-trillion-dollar-disaster-92a4b666c7c7
  57. Goodbye, Object Oriented Programming
    https://cscalfani.medium.com/goodbye-object-oriented-programming-a59cda4c0e53
  58. So You Want to be a Functional Programmer (Part 1)
    https://cscalfani.medium.com/so-you-want-to-be-a-functional-programmer-part-1–1f15e387e536
  59. So You Want to be a Functional Programmer (Part 2)
    https://cscalfani.medium.com/so-you-want-to-be-a-functional-programmer-part-2–7005682cec4a
  60. So You Want to be a Functional Programmer (Part 3)
    https://cscalfani.medium.com/so-you-want-to-be-a-functional-programmer-part-3–1b0fd14eb1a7
  61. So You Want to be a Functional Programmer (Part 4)
    https://cscalfani.medium.com/so-you-want-to-be-a-functional-programmer-part-4–18fbe3ea9e49
  62. So You Want to be a Functional Programmer (Part 5)
    https://cscalfani.medium.com/so-you-want-to-be-a-functional-programmer-part-5-c70adc9cf56a
  63. So You Want to be a Functional Programmer (Part 6)
    https://cscalfani.medium.com/so-you-want-to-be-a-functional-programmer-part-6-db502830403
  64. Why Programmers Need Limits
    https://cscalfani.medium.com/why-programmers-need-limits-3d96e1a0a6db
  65. Signatures
    https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/signature-files
  66. F# for Linux People
    https://carpenoctem.dev/blog/fsharp-for-linux-people/
  67. Ionide project
    https://ionide.io/
  68. FsAutoComplete
    https://ionide.io/Tools/fsac.html
  69. Interactive (.NET for Jupyter Notebook)
    https://github.com/dotnet/in­teractive/#jupyter-and-nteract
  70. let Bindings
    https://github.com/dotnet/doc­s/blob/main/docs/fsharp/lan­guage-reference/functions/let-bindings.md
  71. Lambda Expressions: The fun Keyword (F#)
    https://github.com/dotnet/doc­s/blob/main/docs/fsharp/lan­guage-reference/functions/lambda-expressions-the-fun-keyword.md
  72. Infographic showing code complexity vs developer experience
    https://twitter.com/rossi­pedia/status/1580639227313676288
  73. OCaml for the Masses: Why the next language you learn should be functional
    https://queue.acm.org/deta­il.cfm?id=2038036
  74. Try EIO
    https://patricoferris.github.io/try-eio/
  75. Try OCaml
    https://try.ocaml.pro/
  76. ML – funkcionální jazyk s revolučním typovým systémem
    https://www.root.cz/clanky/ml-funkcionalni-jazyk-s-revolucnim-typovym-systemem/
  77. Funkce a typový systém programovacího jazyka ML
    https://www.root.cz/clanky/funkce-a-typovy-system-programovaciho-jazyka-ml/
  78. Curryfikace (currying), výjimky a vlastní operátory v jazyku ML
    https://www.root.cz/clanky/curryfikace-currying-vyjimky-a-vlastni-operatory-v-jazyku-ml/
  79. Operátor J (Wikipedia)
    https://en.wikipedia.org/wi­ki/J_operator
  80. Standard ML (Wikipedia)
    https://en.wikipedia.org/wi­ki/Standard_ML
  81. Don Syme
    https://en.wikipedia.org/wi­ki/Don_Syme
  82. Python to OCaml: Retrospective
    http://roscidus.com/blog/blog/2014/06/0­6/python-to-ocaml-retrospective/
  83. Xavier Leroy
    https://en.wikipedia.org/wi­ki/Xavier_Leroy
  84. Unit type
    https://en.wikipedia.org/wi­ki/Unit_type
  85. The Option type
    https://fsharpforfunandpro­fit.com/posts/the-option-type/

Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.