Seznam užitečných funkcí v Purescriptu
Odpřednášena v úterý 11. 5.
Užitečné balíčky
Balíček můžete do projektu přidat jednoduše pomocí
> spago install <jméno balíčku bez předpony purescript-> > spago build
Datové struktury
- Pole v Data.Array z
arrays
- Spojový seznam v Data.List z
lists
- Tuple v Data.Tuple z
tuples
- Pro slovníky máme Data.HashMap z
unordered-collections
- Tento přístup, jak napovídá název, používá metodu hashování
- Pokud jsou vaše klíče setřiditelné, můžete preferovat metodu stromovou, pro kterou je Data.Map z
ordered-collections
Hlavní modul s nejběžnější variantou dané datové struktury je vždy ten "topl-level", např. Data.Array
.
Některé datové struktury mají i další varianty, například:
- Lazy modul, např.
Data.Array.Lazy
, který umožňuje dané stuktuře, aby byla nekonečná - ST modul, např.
Data.Array.ST
, který z dané struktury dělá mutable datovou strukturu, za pomocí monádyST
- NonEmpty modul, např.
Data.Array.NonEmpty
, kde je datová struktura upravená tak, že je garantováno, že má alespoň jeden prvek
Zbytek
- V Prelude je většina běžně použivaných funkcí (viz níže)
- Data.Maybe a Data.Either ze stejnojmenných balíčků pro jednoduchou validaci
- Pro práci se soubory Node.FS z
node-fs
Užitečné typeclassy
- Data.Ord, Data.Eq a Data.Show
- Pro mapování funkcí přes věci slouží Functory, definice v Data.Functor
- Collections (tj. datové struktury typu seznam, array, které obsahují několik prvků) jsou skoro vždy Data.Traversable a většinou také Data.Foldable
- Ke kombinování dvou věcí (čísel, stringů, seznamů) slouží Monoidy, definice v Data.Monoid
- Pro kontrolovanou mutaci máme
ST
z modulu Control.Monad.ST, z balíčkust
- Pro obecný control flow (věci typu "dělej tohle dokud něco, pak udělej něco") máme Monády z modulu Control.Monad a Applicative z modulu Control.Applicative
Užitečné funkce
Funkce jsou rozdělené podle modulů. Většina datových struktur podporuje podobný interface (tj podobnou sadu funkcí), jako length
, push
a podobně; pokud máte oblíbenou funkcí v Data.List
, nejspíše ji najdete i v Data.Array
.
Prelude
<>
pro sčítání stringů a ostatních monoidůshow
pro převádění typů, které implementují typeclassuShow
, na stringunit
, jediný obyvatel typuUnit
, což je Purescriptový ekvivalentvoid
z C, tj. je to explicitně napsané "nic"- neplést s
Void
, který má Purescript také, ale znamená něco jiného
- neplést s
top
abottom
, které vezmou nějaký Bounded typ (tj typ, která má hranice, např. Int) a vrátí jeho maximální či minimální hodnotuconst
, funkce, která bere dva argumenty a vždy vrátí ten první z nich (druhý ignoruje)
Functor, Applicative, Monad
map
a její infixní alias<$>
pro mapování funkcí přes Functory (seznamy, stringy, arraye, maybe, ...)apply
a její infixní alias<*>
pro applicative efekty (bude užitečné hlavně časem)bind
a její infixní alias>>=
, potažmodo
-notation (bude užitečné časem),pure
pro "vracení" věcí z monád
Triky s funkcemi
<<<
a>>>
, funkce skládající jiné funkce:(a -> b) -> (b -> c) -> (a -> c)
flip
, který za -> b
funcke uděláb -> a
funkci$
a#
, které vám dovolí nepoužívat závorky, pokud budete chtít- někdy se hodí
on
, která se dá nejlépe vysvětlit typem:(b -> b -> c) -> (a -> b) -> a -> a -> c
- tedy, máte nějaký binární operátor(b -> b -> c)
, a chcete jej aplikovat na dvě věci typua
; vezmete tedy funkcia -> b
, aplikujete jí na oběa
a ty pak zpracujete svým operátorem
Základní operace a definice
otherwise
jako aliastrue
v guardech- logické operace
||
,&&
,not
,==
,/=
- aritmetické operace
+
,-
,/
,*
mod
adiv
(celočíselné dělení)abs
(absolutní hodnota)negate
, změní znaménko u číslalcm
agcd
, které vrátí největší společný násobek, popř. největší společný dělitel
- porovnávací operace,
<
,>
, verze<=
a>=
- funkce
min
,max
- funkce
signum
(vrací -1/0/1) - funkce
between a b
, tedy funkcea <= x <= b
- funkce
clamp
, která omezí nějakou věc mezi vámi zadané hranice, např.(clamp 0 10) -5 == 0
Seznamy a pole
Seznamy z Data.List z lists
a pole z Data.Array z arrays
. Sdílí mnoho funkcí, já zde budu vypisovat jen ty seznamové.
Většina funkcí má i -By variantu (sort
-> sortBy
), která vám umožňuje dodat vlastní porovnávací funkci. Například u sortBy
tak můžete dodat funkci, která bude rozhodovat, který ze dvou prvků je větší — běžný sort
používá obyčejné porovnání.
Vytváření seznamů
Cons
aNil
, popř. infixní alias proCons
je:
- Seznamy se většinou píší jako
1:2:3:4:Nil
:
můžete použít i k pattern matchingu:f (x1:x2:_) = ...
je funkce, která očekává seznam jako první argument a vytáhne si z něj první a druhý prvek a pojmenuje jex1
ax2
- Seznamy se většinou píší jako
singleton :: forall a. a -> List a
, seznam s jedním prvkemrange :: Int -> Int -> List Int
, čísla od-do, popř. infixní alias..
range 1 5 = 1..5 = 1:2:3:4:5:Nil
Rozkládání seznamů
head :: List ~> Maybe
atail :: forall a. List a -> Maybe (List a)
last :: List ~> Maybe
ainit :: forall a. List a -> Maybe (List a)
, pozor, obojí u seznamůO(N)
Map & friends
- mapy
map :: forall a b. (a -> b) -> f a -> f b
mapWithIndex :: forall a b. (Int -> a -> b) -> List a -> List b
mapMaybe :: forall a b. (a -> Maybe b) -> List a -> List b
si nechá jenJust
y, je to tedymap
následovanýcatMaybes
concatMap :: forall a b. (a -> List b) -> List a -> List b
jemap
následovanýconcat
filter :: forall a. (a -> Boolean) -> List a -> List a
zip :: forall a b. List a -> List b -> List (Tuple a b)
zipWith :: forall a b c. (a -> b -> c) -> List a -> List b -> List c
, obecnější verzezip
, která dvojice prvků kombinuje vaš vlastní funkcí- platí vlastně
zip = zipWith Tuple
- platí vlastně
foldl :: forall f a b. Foldable f => (b -> a -> b) -> b -> f a -> b
Přidávání a mazání prvků
snoc :: forall a. List a -> a -> List a
přidá prvek na konec seznamu, pozor, pro seznamy běží vO(N)
insert :: forall a. Ord a => a -> List a -> List a
vloží prvek do setřízeného seznamu, tak, aby zůstal setřízený- změna na indexu
insertAt :: forall a. Int -> a -> List a -> Maybe (List a)
deleteAt :: forall a. Int -> List a -> Maybe (List a)
updateAt :: forall a. Int -> a -> List a -> Maybe (List a)
- popř. pro modifikaci současného pomocí funkce existuje
modifyAt :: forall a. Int -> (a -> a) -> List a -> Maybe (List a)
- pro spojení delete/insert/update existuje `alterAt :: forall a. Int -> (a -> Maybe a) -> List a -> Maybe (List a)
Hledání prvků
- hledání jednoho prvku
l !! i
vytáhnei
-tý prvek zl
(infixní alias proindex l i
)elemIndex :: forall a. Eq a => a -> List a -> Maybe Int
vrátí index prvního prvku, který se rovná tomu hledanémufind :: forall a f. Foldable f => (a -> Boolean) -> f a -> Maybe a
elem :: forall a f. Foldable f => Eq a => a -> f a -> Boolean
any :: forall a b f. Foldable f => HeytingAlgebra b => (a -> b) -> f a -> b
all :: forall a b f. Foldable f => HeytingAlgebra b => (a -> b) -> f a -> b
findIndex :: forall a. (a -> Boolean) -> List a -> Maybe Int
vrátí index prvního prvku, pro který je predikát true
- vybírání několika prvků
slice :: Int -> Int -> List ~> List
vyřízne podseznamtake :: forall a. Int -> List a -> List a
(bere několik ze začátku) adrop :: forall a. Int -> List a -> List a
(vynechá několik ze začátku)takeWhile :: forall a. (a -> Boolean) -> List a -> List a
adropWhile :: forall a. (a -> Boolean) -> List a -> List a
, který berou/vynechávají, dokud je něco pravda
Běžné funkce fungující s celými seznamy
intercalate :: forall f m. Foldable f => Monoid m => m -> f m -> m
Vloží mezi prvky seznamu nějaký prvek, a všechny tyto prvky nakonec zkombinuje pomocí
<>
Hodí se pro práci se stringy
> intercalate ", " ["Lorem", "ipsum", "dolor"] "Lorem, ipsum, dolor" > intercalate [1] [[2, 3], [4, 5], [6, 7]] [2, 3, 1, 4, 5, 1, 6, 7]
null :: forall a. List a -> Boolean
, kontroluje, zda je zenam prázdnýlength :: forall a. List a -> Int
reverse :: List ~> List
sort :: forall a. Ord a => List a -> List a
asortBy :: forall a. (a -> a -> Ordering) -> List a -> List a
nub :: forall a. Ord a => List a -> List a
, který vymaže duplikátyconcat :: forall a. List (List a) -> List a
"zploští" seznamycatMaybes :: forall a. List (Maybe a) -> List a
si nechá jenJust
y- ordering je typ, který obsahuje
LT
(less than),EQ
(equal),GT
(greater than), podle toho paksortBy
pozná, které elementy jsou menší než jiné
- ordering je typ, který obsahuje
Seskupování prvků
group :: forall a. Eq a => List a -> List (NonEmptyList a)
- Group equal, consecutive elements of a list into lists.
- také
groupAll :: forall a. Ord a => List a -> List (NonEmptyList a)
, který grupuje i elementy, které nejsou přímo za sebou v původním seznamu - také
groupBy :: forall a. (a -> a -> Boolean) -> List a -> List (NonEmptyList a)
Množinové operace
difference :: forall a. Eq a => List a -> List a -> List a
, popř. infixní alias\\
intersect :: forall a. Eq a => List a -> List a -> List a
union :: forall a. Eq a => List a -> List a -> List a
Práce se soubory
Funkce z Node.FS.Sync.
FilePath
je jen alias pro String
, Encoding
je kódování souboru (např. Unicode, ASCII, ...), většinou chcete použít UTF8
z Node.Encoding.
readTextFile :: Encoding -> FilePath -> Effect String
writeTextFile :: Encoding -> FilePath -> String -> Effect Unit
(přepíše soubor, pokud existuje)appendTextFile :: Encoding -> FilePath -> String -> Effect Unit
(nepřepíše soubor, ale na konec přidá zadaný text)exists :: FilePath -> Effect Boolean
Práce s adresáři
mkdir :: FilePath -> Effect Unit
(vytvoří adresář)readdir :: FilePath -> Effect (Array FilePath)
(vrátí seznam souborů v adresáři)
Maybe
Z Data.Maybe z balíčku maybe
.
Konstruktory Just a
a Nothing
.
fromMaybe :: forall a. a -> Maybe a -> a
- Takes a default value, and a Maybe value. If the Maybe value is Nothing the default value is returned, otherwise the value inside the Just is returned.
maybe :: forall a b. b -> (a -> b) -> Maybe a -> b
- Takes a default value, a function, and a Maybe value. If the Maybe value is Nothing the default value is returned, otherwise the function is applied to the value inside the Just and the result is returned.
Většinou je nejlepší použít pattern matching, existují však i predikáty isNothing
a isJust
.
Either
Z Data.Either z balíčku either
.
Konstruktory Left a
a Right b
.
Pro konvertování mezi Maybe
a Either
existují funkce hush
a note
.
note :: forall a b. a -> Maybe b -> Either a b
- Takes a default and a Maybe value, if the value is a Just, turn it into a Right, if the value is a Nothing use the provided default as a Left
hush :: forall a b. Either a b -> Maybe b
- Turns an Either into a Maybe, by throwing eventual Left values away and converting them into Nothing. Right values get turned into Justs.
Většinou je nejlepší použít pattern matching, existují však i predikáty isLeft
a isRight
.
Tuple
Z Data.Tuple z balíčku tuples
.
K vytažení prvního (resp. druhého) prvku tuplu slouží funkce fst :: forall a b. Tuple a b -> a
a snd :: forall a b. Tuple a b -> b
.
Pro prohození hodnot je swap :: forall a b. Tuple a b -> Tuple b a
.
Semtam se hodí i funkce uncurry :: forall a b c. (a -> b -> c) -> Tuple a b -> c
.
- Turn a function of two arguments into a function that expects a tuple.
(Hash)Map
Pro hashmapu budou operace stejné, jen nebudou vyžadovat Ord k
.
Běžné operace
empty :: forall k v. Map k v
, založí novou prázdnou Map, popř.singleton :: forall k v. k -> v -> Map k v
, který vyrobí Map s jedním páremlookup :: forall k v. Ord k => k -> Map k v -> Maybe v
member :: forall k v. Ord k => k -> Map k v -> Boolean
insert :: forall k v. Ord k => k -> v -> Map k v -> Map k v
delete :: forall k v. Ord k => k -> Map k v -> Map k v
size :: forall k v. Map k v -> Int
Mohou se hodit
showTree :: forall k v. Show k => Show v => Map k v -> String
, funkce k zobrazení Mapupdate :: forall k v. Ord k => (v -> Maybe v) -> k -> Map k v -> Map k v
alter :: forall k v. Ord k => (Maybe v -> Maybe v) -> k -> Map k v -> Map k v
- Funkce, které udělá insert/delete/update, podle toho, zda daný klíč už v Map je, a zda vaše updatovací funkce
(Maybe v -> Maybe v)
vrací Just nebo Nothing
- Funkce, které udělá insert/delete/update, podle toho, zda daný klíč už v Map je, a zda vaše updatovací funkce
Funkce známé ze seznamů
catMaybes :: forall k v. Ord k => Map k (Maybe v) -> Map k v
filter :: forall k v. Ord k => (v -> Boolean) -> Map k v -> Map k v
- Filter out those key/value pairs of a map for which a predicate on the value fails to hold
- podobně
filterWithKey :: forall k v. Ord k => (k -> v -> Boolean) -> Map k v -> Map k v
mapMaybe :: forall k a b. Ord k => (a -> Maybe b) -> Map k a -> Map k b
- Applies a function to each value in a map, discarding entries where the function returns Nothing.
- podobně
mapMaybeWithKey :: forall k a b. Ord k => (k -> a -> Maybe b) -> Map k a -> Map k b
Množinové operace
- sjednocení
union :: forall k v. Ord k => Map k v -> Map k v -> Map k v
- průnik
intersection :: forall k a b. Ord k => Map k a -> Map k b -> Map k a
- rozdíl
difference :: forall k v w. Ord k => Map k v -> Map k w -> Map k v