Operátory v programovacím jazyku F#

7. 11. 2023
Doba čtení: 41 minut

Sdílet

Autor: Depositphotos
Operátory hrají v jazycích odvozených od jazyka ML podstatnou roli. Jedná se jak o standardní operátory, tak i o možnost vytvoření operátorů zcela nových, u nichž lze určit i jejich prioritu a asociativitu.

Obsah

1. Operátory v programovacím jazyku F#

2. Standardní operátory jazyka F#

3. Unární aritmetické operátory

4. Binární aritmetické operátory

5. Úskalí jazyka s přetíženými operátory

6. Logické (Booleovské) operátory

7. Operátory provádějící zvolenou operaci bit po bitu, bitové posuny

8. Relační operátory

9. Operátory pro spojování řetězců a seznamů

10. Šipky kam se člověk podívá

11. Základní operátory pro tvorbu kolony

12. Další operátory pro tvorbu kolony

13. Operátory pro kompozici funkcí

14. Konstrukce nového binárního operátoru

15. Předeklarování existujícího operátoru

16. Rozlišení unárního a binárního operátoru

17. Asociativa nových operátorů

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

19. Literatura

20. Odkazy na Internetu

1. Operátory v programovacím jazyku F#

Operátory hrají v programovacích jazycích odvozených od jazyka ML podstatnou roli. Jedná se jak o standardní operátory (v OCamlu jich existuje téměř čtyřicet, v jazyku F# je nepatrně méně), tak i o možnost vytvoření operátorů zcela nových, u nichž lze dokonce určit i jejich prioritu a asociativitu. Vlastnosti existujících i nových operátorů dostupných v programovacím jazyce F# budou tématem dnešního článku. Doplníme tedy (nepatrně) starší článek, v němž jsme se tomuto tématu věnovali primárně z pohledu programovacího jazyka OCaml, který je chápán jako ideový předchůdce programovacího jazyka F#.

V dnešním článku se ovšem již nebudeme zabývat „teoretickými“ problémy, které souvisí s definicí nových operátorů, protože tyto kapitoly jsou pro OCaml a F# prakticky stejné a nemá smysl je znovu opakovat. V případě potřeby si příslušné kapitoly „nalistujte“ pod těmito odkazy:

2. Standardní operátory jazyka F#

V programovacím jazyce F# nalezneme celkem 36 standardních operátorů, tj. operátorů, u kterých je nejenom přesně specifikována prováděná operace, ale taktéž datové typy operandu či (obou) operandů; v závislosti na tom, zda se jedná o unární či o binární operátor. Jedná se o následující operátory:

 
    =        <>       <         >
    <=       >=       <<<       >>>
    &&       &        ||        not
    &&&      |||      ^^^       ~~~
    +        -        *         /
    ^        @        %         **
    :>       :?       :?>       ->
    >>       |>       ||>       |||>
    <<       <|       <||       <|||
 
Poznámka: tato skupina operátorů se v mnoha ohledech odlišuje od operátorů, které nalezneme v jazyku OCaml. Rozdíly vychází především z toho, že v F# již nerozlišujeme mezi celočíselnými operátory a operátory nad hodnotami s plovoucí řádovou čárkou. A na druhou stranu v jazyku F# máme k dispozici celou řadu operátorů určených pro práci s typy a pro různé varianty kompozice funkcí popř. vytváření „kolony“ funkcí. Navíc se některé „pojmenované“ operátory v OCaml (lsr) změnily na „paznakové“ operátory v jazyce F#. V OCamlu máme k dispozici tyto operátory:
 
    =        <>       <         >
    <=       >=       ==        !=
    &&       &        ||        |
    |>       @@       **        ^
    +        -        *         /
    +.       -.       *.        /.
    ~+       ~-       ~+.       ~-.
    @        !        :=        ^^
    mod      land     lor      lxor
    lsl      lsr      asr
 

3. Unární aritmetické operátory

Začneme popisem unárních aritmetických operátorů, protože jejich popis je snadný. Unární operátory akceptují jediný operand na své pravé straně. Nejprve si pro porovnání připomeňme, že v jazyce OCaml byla k dispozici čtveřice unárních operátorů:

Operátor Vstupní operand Výsledek Popis operátoru
~- int int unární – (změna znaménka)
~+ int int unární +
       
~-. float float unární – (změna znaménka)
~+. float float unární +

Programovací jazyk F# naproti tomu již nevyžaduje ani tildu na začátku unárních operátorů (ta již ovšem není povinná ani v OCamlu), ovšem navíc nerozlišuje ani mezi operátory pro numerické datové ze skupiny int a float – příslušný (přetížený) operátor se totiž určí automaticky na základě pravého operandu (pochopitelně s tím, že výsledná, tedy vypočtená, hodnota je stejného typu jako pravý operand):

Operátor Vstupní operand Výsledek Popis operátoru
int int unární – (změna znaménka)
+ int int unární +
float float unární – (změna znaménka)
+ float float unární +
Poznámka: zde i v dalším textu je možné za typ int doplnit i byte, sbyte, int16, uint16, int32, uint32, int64, uint64, nativeint a unativeint.

Příklad použití unárních aritmetických operátorů s hodnotami typu int:

let x = 10
let y = 20
 
let z = -x
let w = +y
 
printf "%d" x
printf "%d" y
printf "%d" z
printf "%d" w

Příklad použití unárních aritmetických operátorů s hodnotami typu float:

let x = 0.5
let y = 0.5
 
let z = -x
let w = +y
 
printf "%f" x
printf "%f" y
printf "%f" z
printf "%f" w
Poznámka: některé verze jazyka F# nepodporují unární operátor +, což ale v praxi nemusí vůbec vadit.

Ještě lépe je funkce typového systému programovacího jazyka F# patrná při práci v interaktivní konzoli:

> let x=10;;
val x: int = 10
 
> -x;;
val it: int = -10
 
> +x;;
val it: int = 10
 
> let y=3.14;;
val y: float = 3.14
 
> -y;;
val it: float = -3.14
 
> +y;;
val it: float = 3.14

Vzhledem k tomu, že tyto unární operátory vždy zajišťují, že výsledek je stejného typu, jako vstupní hodnota, není možné operátor „-“ použít pro celočíselné typy bez znaménka:

val z: byte = 255uy
 
> +z;;
val it: byte = 255uy
 
> -z;;
 
  -z;;
    -^
 
error FS0001: The type 'byte' does not support the operator '~-'
 
 
 
val w: uint16 = 1us
 
> +w;;
val it: uint16 = 1us
 
> -w;;
 
  -w;;
    -^
 
error FS0001: The type 'uint16' does not support the operator '~-'
Poznámka: totéž omezení pochopitelně platí pro všechny celočíselné typy bez znaménka.

4. Binární aritmetické operátory

Následuje tabulka s binárními operátory. V jazyce OCaml jsou tyto operátory opět rozděleny podle toho, zda jsou definovány pro operandy typu int či float (devátý operátor je definován pouze pro typ float):

Operátor Vstupní operandy Výsledek Popis operátoru
+ int int součet
int int rozdíl
* int int součin
/ int int podíl
mod int int zbytek po celočíselném dělení
       
+. float float součet
-. float float rozdíl
*. float float součin
/. float float podíl
** float float umocnění

Naproti tomu v jazyce F# se již nerozlišuje mezi operátory pro typ int a float, takže se tabulka zjednodušuje (a sémantika jazyka je složitější):

Operátor Vstupní operandy Výsledek Popis operátoru
+ int int součet
int int rozdíl
* int int součin
/ int int podíl
% int int zbytek po celočíselném dělení
       
+ float float součet
float float rozdíl
* float float součin
/ float float podíl
% float float zbytek po celočíselném dělení, ovšem jako hodnota typu float
** float float umocnění

Tabulka je rozdělena korektně, protože oba operandy nějakého aritmetického binárního operátoru musí být shodného typu, což je kontrolováno při překladu.

Poznámka: jediným operátorem, který je určen pro zpracování hodnot jediného datového typu, je operátor **. Kupodivu je možné použít operátor % i s hodnotami typu float; výsledkem bude taktéž hodnota typu float (i když za desetinnou tečkou budou nuly).

Ukázka použití těchto operátorů pro hodnoty typu int:

> let a=10;;
val a: int = 10
 
> let b=3;;
val b: int = 3
 
> a+b;;
val it: int = 13
 
> a-b;;
val it: int = 7
 
> a*b;;
val it: int = 30
 
> a/b;;
val it: int = 3
 
> a%b;;
val it: int = 1
 
> a**b;;
 
  a**b;;
    ^
 
error FS0001: The type 'int' does not support the operator 'Pow'

Ukázka použití těchto operátorů pro hodnoty typu float:

val x: float = 4.5
 
> let y=1.5;;
val y: float = 1.5
 
> x+y;;
val it: float = 6.0
 
> x-y;;
val it: float = 3.0
 
> x*y;;
val it: float = 6.75
 
> x/y;;
val it: float = 3.0
 
> x%y;;
val it: float = 0.0
 
> x**y;;
val it: float = 9.545941546

5. Úskalí jazyka s přetíženými operátory

Typové definice jednotlivých operátorů si lze nechat vypsat na interaktivní konzole po zápisu:

( operátor );;

V jazyku OCaml nejsou základní aritmetické operátory přetížené, takže jejich typové definice jsou jednoznačné:

( + ) ;;
- : int -> int -> int = <fun>
 
( - ) ;;
- : int -> int -> int = <fun>
 
( * ) ;;
- : int -> int -> int = <fun>
 
( / ) ;;
- : int -> int -> int = <fun>
 
( +. ) ;;
- : float -> float -> float = <fun>
 
( -. ) ;;
- : float -> float -> float = <fun>
 
( *. ) ;;
- : float -> float -> float = <fun>
 
( /. ) ;;
- : float -> float -> float = <fun>
 
( ** ) ;;
- : float -> float -> float = <fun>

V programovacím jazyku F# je však situace odlišná, protože například operátor + lze použít pro všechny celočíselné typy i pro typy s plovoucí řádovou čárkou. Bez uvedení dalšího kontextu tak získáme typové informace pouze pro jedinou variantu operátoru:

> (+);;
val it: (int -> int -> int) = <fun:it@66>
 
> (-);; 
val it: (int -> int -> int) = <fun:it@67-1>
 
> (*);;
val it: (int -> int -> int) = <fun:it@68-2>
 
> (/);;
val it: (int -> int -> int) = <fun:it@69-3>
 
> (%);;
val it: (int -> int -> int) = <fun:it@70-4>
Poznámka: zde není možné použít obecný generický typ 'a, protože aritmetické operátory obecně nejsou použitelné pro všechny typy (musely by se explicitně přetížit, což je téma navazujícího textu).

6. Logické (Booleovské) operátory

Tato kapitola bude velmi krátká, protože programátoři mají v jazyce F# k dispozici pouze tři standardní booleovské operátory. Jedná se o logický součin, logický součet a logickou negaci:

Operátor Vstupní operandy Výsledek Popis operátoru
&& bool bool logický součin
|| bool bool logický součet
not bool bool logická negace

Zjištění typových informací o těchto operátorech:

> (&&);;  
val it: (bool -> bool -> bool) = <fun:it@75-5>
 
> (||);;
val it: (bool -> bool -> bool) = <fun:it@76-6>
 
> (not);;
val it: (bool -> bool) = <fun:it@77-7>

Příklady použití:

> let u=true;;
val u: bool = true
 
> let v=false;;
val v: bool = false
 
> u && v;;
val it: bool = false
 
> u || v;;
val it: bool = true
 
> not u;;
val it: bool = false
 
> not v;;
val it: bool = true

Z důvodu zpětné kompatibility se ještě můžete se setkat i se starším zápisem operátoru && pomocí jediného znaku &. Ovšem překladač bude v tomto případě vypisovat varování, že se má použít „zdvojená“ varianta operátoru (nicméně výpočet se provede):

> u & v;;
 
  u & v;;
    --^
 
warning FS1203: In F# code, use 'e1 && e2' instead of 'e1 & e2'
 
val it: bool = false

7. Operátory provádějící zvolenou operaci bit po bitu, bitové posuny

Následují operace, které jsou prováděny bit po bitu a navíc do této skupiny zařadíme i operace určené pro provádění bitových posunů a aritmetického posunu doprava. Zajímavé je, že všechny zmíněné operace se v jazyku F# zapisují „ztrojeným“ znakem tak, jak je to naznačeno v tabulce zobrazené pod tímto odstavcem:

Operátor Vstupní operandy Výsledek Popis operátoru
&&& int int bitová operace and
||| int int bitová operace or
^^^ int int bitová operace xor
~~~ int int negace bit po bitu
       
<<< int int bitový posun doleva
>>> int int bitový nebo aritmetický posun doprava

Opět se podívejme na typové informace o těchto operátorech:

> ( &&& );;
val it: (int -> int -> int) = <fun:it@9-8>
 
> ( ||| );;
val it: (int -> int -> int) = <fun:it@10-9>
 
> ( ^^^ );;
val it: (int -> int -> int) = <fun:it@11-10>
 
> ( ~~~ );;
val it: (int -> int) = <fun:it@12-11>
 
> ( <<< );;
val it: (int -> int32 -> int) = <fun:it@13-12>
 
> ( >>> );;
val it: (int -> int32 -> int) = <fun:it@14-13>
Poznámka1: u všech operací lze použít hodnoty typu byte, sbyte, int16, uint16, int32, uint32, int64, uint64, nativeint a unativeint. Pouze druhý operand u bitových posunů musí být typu int32.
Poznámka2: u posunu doprava záleží na tom, zda se posunuje hodnota bez znaménka (potom se použije bitový posun) nebo se znaménkem (potom se použije posun aritmetický, tedy s kopií nejvyššího bitu).

Použití těchto operátorů je snadné:

let x = 0b0011
let y = 0b0101
 
printf "%x\n" (x &&& y)
printf "%x\n" (x ||| y)
printf "%x\n" (x ^^^ y)
printf "%x\n" (~~~ x)
printf "%x\n" (~~~ y)

S výsledky:

1
7
6
fffffffc
fffffffa

Bitové posuny:

printf "%d\n" (1 <<< 10)
printf "%d\n" (1000 >>> 1)
printf "%d\n" (-1000 >>> 1)

S výsledky:

1024
500
-500

8. Relační operátory

Relační operátory jsou v programovacím jazyku F# realizovány takovým způsobem, že oba operandy musí být sice stejného typu, ovšem tímto typem mohou být jak číselné hodnoty, tak i řetězce, seznamy, pole atd.

Operátor Vstupní operandy Výsledek Popis operátoru
< 'a bool test na relaci „menší než“
<= 'a bool test na relaci „menší nebo rovno“
> 'a bool test na relaci „větší než“
>= 'a bool test na relaci „větší nebo rovno“
= 'a bool strukturální ekvivalence
<> 'a bool opak =

Ostatně se můžeme sami snadno přesvědčit, jaké typové informace o těchto operátorech je možné získat:

> (<);;  
val it: ('a -> 'a -> bool) when 'a: comparison
 
> (>);;
val it: ('a -> 'a -> bool) when 'a: comparison
 
> (<=);;
val it: ('a -> 'a -> bool) when 'a: comparison
 
> (>=);;
val it: ('a -> 'a -> bool) when 'a: comparison
 
> (=);; 
val it: ('a -> 'a -> bool) when 'a: equality
 
> (<>);;
val it: ('a -> 'a -> bool) when 'a: equality
Poznámka: povšimněte si, že se ve skutečnosti jedná o dvě kategorie operátorů – comparison a equality.

Příklady použití těchto operátorů společně s číselnými hodnotami:

let x = 1
let y = 2
 
printf ">  %b\n" (x>y)
printf "<  %b\n" (x<y)
printf ">= %b\n" (x>=y)
printf "<= %b\n" (x<=y)
printf "=  %b\n" (x=y)
printf "<> %b\n" (x<>y)

V jazyku F# můžeme porovnávat i řetězce (lexikografické porovnání):

let x = "foo"
let y = "bar"
 
printf ">  %b\n" (x>y)
printf "<  %b\n" (x<y)
printf ">= %b\n" (x>=y)
printf "<= %b\n" (x<=y)
printf "=  %b\n" (x=y)
printf "<> %b\n" (x<>y)

Porovnat lze ovšem například také pole:

let x = [|1,2|]
let y = [|1,2|]

printf ">  %b\n" (x>y)
printf "<  %b\n" (x<y)
printf ">= %b\n" (x>=y)
printf "<= %b\n" (x<=y)
printf "=  %b\n" (x=y)
printf "<> %b\n" (x<>y)

Zajímavé je, že se dají porovnávat i seznamy. Opět se jedná o lexikografické porovnání s tím, že pokud je relace zaručena pro n-tý prvek, porovnání se v tomto místě zastaví. To je patrné na posledních třech příkladech, kdy postačuje porovnat druhý resp. první prvek:

printf "%b\n" ([1,2,3] < [4,5,6])
printf "%b\n" ([1,2,3] < [1,2,3])
printf "%b\n" ([1,2,3] < [1,2,4])
printf "%b\n" ([1,2,3] < [9,2,4])
printf "%b\n" ([1,2,3] < [9,0,0])
printf "%b\n" ([1,2,3] < [9,-1000,-1000])
Poznámka: kromě druhého řádku se v ostatních řádcích vypočte a zobrazí výsledek true.

9. Operátory pro spojování řetězců a seznamů

Další operátory, které v jazyce F# nalezneme, slouží ke spojování řetězců nebo seznamů. I když pracují s různými typy, popíšeme si je v jedné kapitole:

Operátor Vstupní operandy Výsledek Popis operátoru
@ seznam 'a seznam 'a spojení dvou seznamů s prvky stejných typů
^ řetězec řetězec spojení dvou řetězců

Nejprve si vypišme typy obou operátorů. Ty naznačí, že namísto ^ by se měl používat přetížený operátor + (na rozdíl od OCamlu):

> ( ^ );;
 
  ( ^ );;
    --^
 
warning FS0062: This construct is for ML compatibility. Consider using the '+'
operator instead. This may require a type annotation to indicate it acts on
strings. This message can be disabled using '--nowarn:62' or '#nowarn "62"'.
 
val it: (string -> string -> string) = <fun:it@3-2>
 
> ( @ );;
val it: ('a list -> 'a list -> 'a list)

Příklad spojení seznamů:

let x = [1; 2; 3]
let y = [1..10]
let z = x @ y
 
printf "%A" z

Výsledkem bude tento seznam:

[1; 2; 3; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10]

10. Šipky kam se člověk podívá

Zbývá nám popsat následující skupiny operátorů:

    :>       :?>      ->
    >>       |>       ||>       |||>
    <<       <|       <||       <|||

Operátory na prvním řádku souvisí s uživatelskými datovými typy, což je koncept, kterému se budeme podrobněji věnovat příště, takže se těmito operátory budeme zabývat později. V navazujících kapitolách si tedy popíšeme osm „šipkových“ operátorů:

    >>       |>       ||>       |||>
    <<       <|       <||       <|||

11. Základní operátory pro tvorbu kolony

Operátory |> a |< slouží pro konstrukci takzvané kolony (pipeline), s níž jsme se již v tomto seriálu setkali. Díky existenci kolony můžeme velmi snadno předávat hodnotu z jedné funkce do další funkce a zřetězit tak volání libovolného množství funkcí (za předpokladu, že se předává jediná hodnota). Vstupem do kolony je nějaká hodnota:

let inc x = x+1
let double x = x*2
 
let x = 10 |> double |> inc
printf "%d\n" x
Poznámka: asociativita je intuitivní – zleva doprava.

Operátor <| taktéž představuje kolonu, ovšem zkonstruovanou v opačném směru. Hodnota vstupuje do kolony zprava a postupně se prochází zprava doleva (což musíme naznačit závorkami):

let inc x = x+1
let double x = x*2
 
let x = double <| (inc <| 10)
printf "%d\n" x

Zajímavé bude zjištění typů těchto dvou operátorů:

> ( |> );;
val it: ('a -> ('a -> 'b) -> 'b)
 
> ( <| );;
val it: (('a -> 'b) -> 'a -> 'b)

12. Další operátory pro tvorbu kolony

V programovacím jazyku F# ovšem nalezneme ještě další čtyři operátory určené pro tvorbu kolon. Tyto operátory opět používají šipky, které naznačují směr toku dat, ovšem mají zdvojen či dokonce ztrojen znak „|“. Tím je naznačeno, kolik hodnot se v koloně předává do další funkce. U operátorů z předchozí kapitoly to je jedna hodnota, u operátorů z této kapitoly dvojice či trojice.

Tyto těchto operátorů mohou napovědět:

> ( ||> );;
val it: ('a * 'b -> ('a -> 'b -> 'c) -> 'c)
 
> ( |||> );;
val it: ('a * 'b * 'c -> ('a -> 'b -> 'c -> 'd) -> 'd)
 
> ( <|| );; 
val it: (('a -> 'b -> 'c) -> 'a * 'b -> 'c)
 
> ( <||| );;
val it: (('a -> 'b -> 'c -> 'd) -> 'a * 'b * 'c -> 'd)

Pro zajímavost se podívejme na několik příkladů.

Předání dvojice hodnot v koloně:

let add x y = x+y
 
let x = (1, 2) ||> add
printf "%d\n" x

Několik funkcí v koloně:

let sub x y = x-y
let swap x y = (y, x)
 
let x = (1, 2) ||> sub
printf "%d\n" x
 
let y = (1, 2) ||> swap ||> sub
printf "%d\n" y

Výsledky by měly být následující:

-1
1

Předání trojice hodnot do funkce typu multiply-accumulate:

let madd x y z = x*y+z
 
let x = (3, 2, 1) |||> madd
printf "%d\n" x

S výsledkem:

7
Poznámka: podobně by se pracovalo s operátory, které předávají data zprava doleva.

13. Operátory pro kompozici funkcí

Poslední dva standardní operátory programovacího jazyka F#, které nám ještě zbývá popsat, se zapisují s využitím dvojice znaků >> a <<. Tyto operátory nám umožňují zkonstruovat novou funkci s využitím takzvané kompozice funkcí, což je velmi elegantní funkcionální technika, kterou nalezneme i u některých dalších programovacích jazyků. Při kompozici funkcí se nespecifikují operandy ani způsob přenosu návratové hodnoty jedné funkce do funkce druhé. Pouze se určuje, které funkce mají být spojeny do nové funkce.

Ve skutečnosti je to poměrně snadné. Podívejme se na velmi jednoduchý příklad, v němž z funkce inc a double vytvoříme novou funkci nazvanou f1. Tuto funkci následně zavoláme:

let inc x = x+1
let double x = x*2
 
let f1 = inc >> double
printf "%d\n" (f1 1)

Nová funkce f1 pracuje tak, že nejprve zvýší hodnotu svého parametru (volá inc) a výsledek vynásobí dvěma (volá double). Výsledkem tedy bude hodnota (1+1)×2=4:

4

Namísto operátoru >> ovšem můžeme použít i operátor <<. Ten taktéž vytvoří novou funkci s využitím kompozice dvou jiných funkcí, ovšem funkce budou „uzávorkovány“ naopak: funkce1(funkce2(parametry)). Opět si to pochopitelně můžeme ověřit na funkcích inc a double:

let inc x = x+1
let double x = x*2
 
let f1 = inc << double
printf "%d\n" (f1 1)

Nyní bude výsledek odlišný, neboť se nejprve vypočte 1×2 a následně se k výsledku připočte jednička:

3

Operátory pro kompozici funkcí můžeme zřetězit:

let inc x = x+1
let double x = x*2
 
let f1 = double >> inc >> double
printf "%d\n" (f1 1)

Nyní bude výsledkem tato hodnota (pravděpodobně je zřejmé, jak k ní došlo):

6

Na závěr této kapitoly si ukažme, jaké jsou typové definice obou operátorů zajišťujících kompozici funkcí:

> ( >> );;
val it: (('a -> 'b) -> ('b -> 'c) -> 'a -> 'c)
 
> ( << );;
val it: (('a -> 'b) -> ('c -> 'a) -> 'c -> 'b)

14. Konstrukce nového binárního operátoru

V programovacím jazyku F# je umožněna tvorba nových operátorů. Při volbě znaku či znaků pro reprezentaci operátoru je možné vybírat z této skupiny:

!, $, %, &, *, +, -, ., /, <, =, >, ?, @, ^, |

Zkusme si například nadeklarovat operátor nazvaný +?, který implementuje výpočet x2+y2. Jedná se tedy o klasický binární operátor (se dvěma operandy):

let (+?) (x: int) (y: int) = x*x + y*y
printf "%d" (3 +? 4)

Po překladu a spuštění tohoto demonstračního příkladu se zobrazí očekávaný výsledek 25:

25
Poznámka: priorita operátoru je určena jeho prvním znakem. V tomto případě tedy bude mít operátor stejnou prioritu jako standardní operátor +.

15. Předeklarování existujícího operátoru

Demonstrační příklad z předchozí kapitoly je možné nepatrně upravit tak, že předeklarujeme standardní operátor +. Po následující definici bude operátor + definován pouze pro celá čísla typu int a přestane být přetížený pro řetězce, seznamy atd.:

let (+) (x: int) (y: int) = x + y + 1
printf "%d" (3 + 4)

Výsledek:

8
Poznámka: v naprosté většině případů je taková předeklarace standardního operátoru velmi špatným nápadem. Praktičtější bývá operátor přetížit pro (nový) datový typ, což bude téma navazujícího článku.

16. Rozlišení unárního a binárního operátoru

Z předchozího textu již víme, jakým způsobem je možné vytvořit nový binární operátor popř. jak lze předefinovat nějaký stávající operátor. Ovšem prozatím nevíme, jak zajistit tvorbu unárního operátoru, tedy operátoru, který se zapisuje před svůj jediný operand. Pro odlišení unárního operátoru od operátoru binárního se používá znak tildy, ovšem jen při deklaraci operátoru (nikoli při jeho použití).

Následující zápis tedy značí deklaraci a následné použití binárního operátoru nazvaného %%:

let (%%) (x: int) (y: int) = x + y
printf "%d" (3 %% 4)

Naproti tomu tento zápis značí deklaraci a následné použití operátoru unárního (se stejným jménem):

let (~%%) (x: int) = x * x
printf "%d" (%% 4)
Poznámka: povšimněte si, že se tilda skutečně používá jen při deklaraci operátoru.

17. Asociativa nových operátorů

Operátory mají v programovacím jazyce F# různou prioritu i různou asociativitu. Buď se jedná o asociativitu zleva (tedy výraz se stejnými operátory je „uzávorkován“ ve stylu:

(((x ⊕ y) ⊕ z) ⊕ w)

pro nějaký operátor ⊕. Nebo může mít operátor asociativitu zprava (resp. být asociativní zprava), takže jeho automatické „uzávorkování“ bude odlišné:

(x ⊕ (y ⊕ (z ⊕ w)))

Asociativity operátorů jsou vypsány v následující tabulce:

Operátory Asociativita
| (pipe) zleva
not zprava
-> zprava
:= zprava
, bez asociativity
or, || zleva
&, && zleva
:>, :?> zprava
<op, >op, =, |op, &op, &, $ zleva
<<<, >>>, |||, &&& zleva
^op (včetně ^^^) zprava
:: zprava
-op, +op zleva
*op, /op, %op zleva
**op zprava
prefixové operátory (+op, -op, %, %%, &, &&, !op, ~op) zleva
. zleva

Podívejme se nyní na to, jakou asociativitu bude mít nový operátor %%. Podle předchozí tabulky by měl být asociativní zleva, takže si to pojďme ověřit:

let (%%) (x: int) (y: int)= x - y
printf "%d" (1 %% 2 %% 3)

Výsledek je vypočten jako (1–2)-3, tedy –1–3=-4:

-4

Naproti tomu výše uvedená tabulka naznačuje, že operátor ^? by měl být asociativní zprava:

bitcoin školení listopad 24

let (^?) (x: int) (y: int)= x - y
printf "%d" (1 ^? 2 ^? 3)

Nyní je výpočet proveden odlišně: 1-(2–3), tedy 1-(-1)=2:

2
Poznámka: to, že je asociativita (a taktéž priorita) určena prvním znakem operátoru, je výhoda i nevýhoda současně. Výhodou je, že pohledem na výpočet lze zjistit, jak bude probíhat. Nevýhodou je, že si vývojář musí tabulky pamatovat nebo k nim mít stále přístup.

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
       
110 article06/unary_ops1.fs unární aritmetické operátory a datový typ int https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle06/unary_ops1.fs
111 article06/unary_ops2.fs unární aritmetické operátory a datový typ float https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle06/unary_ops2.fs
112 article06/binary_ops.fs binární aritmetické operátory a datový typ int https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle06/binary_ops.fs
113 article06/boolean.fs Booleovské unární i binární operátory https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle06/boolean.fs
114 article06/relational1.fs relační operátory, porovnání hodnot typu int https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle06/relational1.fs
115 article06/relational2.fs relační operátory, porovnání hodnot typu string https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle06/relational2.fs
116 article06/relational3.fs relační operátory, porovnání hodnot typu array https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle06/relational3.fs
117 article06/relational4.fs relační operátory, porovnání hodnot typu array https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle06/relational4.fs
118 article06/bit_operators.fs operátory provádějící operaci bit po bitu https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle06/bit_operators.fs
119 article06/shifts.fs operátory pro bitové a aritmetické posuny https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle06/shifts.fs
       
120 article06/func_pipeline1.fs kolona funkcí vytvořená operátorem |> https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle06/func_pipeline1.fs
121 article06/func_pipeline2.fs kolona funkcí vytvořená operátorem <| https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle06/func_pipeline2.fs
122 article06/func_pipeline3.fs kolona funkcí vytvořená operátorem ||> https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle06/func_pipeline3.fs
123 article06/func_pipeline4.fs kolona funkcí vytvořená operátorem ||> https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle06/func_pipeline4.fs
124 article06/func_pipeline5.fs kolona funkcí vytvořená operátorem |||> https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle06/func_pipeline5.fs
       
125 article06/func_composition1.fs kompozice dvou funkcí operátorem >> https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle06/func_composition1.fs
126 article06/func_composition2.fs kompozice dvou funkcí operátorem << https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle06/func_composition2.fs
127 article06/func_composition3.fs kompozice tří funkcí operátorem >> https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle06/func_composition3.fs
       
128 article06/new_operator1.fs definice nového binárního operátoru https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle06/new_operator1.fs
129 article06/new_operator2.fs přepis stávajícího binárního operátoru https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle06/new_operator2.fs
130 article06/new_operator3.fs rozlišení unárního a binárního operátoru https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle06/new_operator3.fs
131 article06/new_operator4.fs rozlišení unárního a binárního operátoru https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle06/new_operator4.fs
132 article06/new_operator5.fs otestování asociativity operátoru https://github.com/tisnik/f-sharp-examples/tree/master/arti­cle06/new_operator5.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. Don Syme
    https://en.wikipedia.org/wi­ki/Don_Syme
  65. Python to OCaml: Retrospective
    http://roscidus.com/blog/blog/2014/06/0­6/python-to-ocaml-retrospective/
  66. Why Programmers Need Limits
    https://cscalfani.medium.com/why-programmers-need-limits-3d96e1a0a6db
  67. Signatures
    https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/signature-files
  68. F# for Linux People
    https://carpenoctem.dev/blog/fsharp-for-linux-people/
  69. Ionide project
    https://ionide.io/
  70. FsAutoComplete
    https://ionide.io/Tools/fsac.html
  71. Interactive (.NET for Jupyter Notebook)
    https://github.com/dotnet/in­teractive/#jupyter-and-nteract
  72. let Bindings
    https://github.com/dotnet/doc­s/blob/main/docs/fsharp/lan­guage-reference/functions/let-bindings.md
  73. 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
  74. Infographic showing code complexity vs developer experience
    https://twitter.com/rossi­pedia/status/1580639227313676288
  75. OCaml for the Masses: Why the next language you learn should be functional
    https://queue.acm.org/deta­il.cfm?id=2038036
  76. Try EIO
    https://patricoferris.github.io/try-eio/
  77. Try OCaml
    https://try.ocaml.pro/
  78. ML – funkcionální jazyk s revolučním typovým systémem
    https://www.root.cz/clanky/ml-funkcionalni-jazyk-s-revolucnim-typovym-systemem/
  79. Funkce a typový systém programovacího jazyka ML
    https://www.root.cz/clanky/funkce-a-typovy-system-programovaciho-jazyka-ml/
  80. 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/
  81. Operátor J (Wikipedia)
    https://en.wikipedia.org/wi­ki/J_operator
  82. Standard ML (Wikipedia)
    https://en.wikipedia.org/wi­ki/Standard_ML
  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/
  86. Operators
    https://ocaml.org/docs/operators
  87. Operator overloading
    https://en.wikipedia.org/wi­ki/Operator_overloading

Autor článku

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