Списъкът е основна структура данни във функционалните езици. Затова и съществуват множество функции, които правят работата с тях по-лесна. Познаването и използването на тези функции спомага за по-лесната взаимо-работа с други хора и по-малко време отделено в преоткриване на колелото.
Ще дефинираме следните функции върху списъци от числа, но алтернативи със същите имена се намират в пакета Data.List
и работят върху списъци от произволен тип. Най-често ползваните от тях са налична дори без импортирането на Data.List
, тъй като са толкова основни, че са включени в Prelude
- модулът, предоставящ "вградените" типове и операции.
Тази задача има базови Unit tests. Те се намират в ListTests.hs
и следват като конвенция името на фунцкията с добавено Test
отзад.
Пр: null
-> nullTest
.
За да ги пуснете, заредете файла ListTests.hs
в ghci и използвайте:
putStrLn (runTests [nullTest, lengthTest])
за да изпълните тестовете за null
и length
съответно.
putStrLn (runTests allTests)
изпълнява всички тестове.
head :: [Int] -> Int
Взима първия елемент на списъка. Ако списъкът е празен, хвърля грешка.
> head [1, 2, 3]
1
> head []
** Exception: empty list
tail :: [Int] -> [Int]
Връща опашката на списъка. Ако списъкът е празен, хвърля грешка.
> tail [1, 2, 3]
[2, 3]
> tail []
** Exception: empty list
append :: [Int] -> [Int] -> [Int]
Слепва два списъка. Стандартната операция за append
от Prelude
е операторът ++
.
> append [1, 2, 3] [4, 5, 6]
[1, 2, 3, 4, 5, 6]
> [1, 2, 3] ++ [4, 5, 6]
[1, 2, 3, 4, 5, 6]
elementAt :: Int -> [Int] -> Int
Връща n
-тия елемент от списък. Ако списъкът е по-къс или индексът е отрицателен, хвърля грешка. Стандартният оператор от Prelude
е !!
.
> elementAt 0 [1, 2, 3]
1
> elementAt 4 [1, 2, 3]
** Exception: index too large
> [1, 2, 3, 4] !! 1
2
null :: [Int] -> Bool
Проверява дали подаденият списък е празен.
> null [1, 2, 3]
False
> null []
True
length :: [Int] -> Int
Връща големината на списъка.
> length [1, 2, 3]
3
> length []
0
take :: Int -> [Int] -> [Int]
Взима първите n
елемента от списък. Ако n
е отрицателно връща празен списък. Ако списъкът е по-къс, взима възможно най-голям брой елементи, без да хвърля грешки.
> take 2 [1, 2, 3]
[1, 2]
> take 5 []
[]
drop :: Int -> [Int] -> [Int]
Премахва първите n
елемента от списък. Ако n
е отрицателно връща списъка непроменен. Ако списъкът е по-къс, премахва възможно най-голям брой елементи, без да хвърля грешки.
> drop 2 [1, 2, 3]
[3]
> drop 5 []
[]
elem :: Int -> [Int] -> Bool
Проверява дали подаденият елемент е част от списъка. Връща True
ако да.
> elem 2 [1, 2, 3]
True
> elem 5 []
False
reverse :: [Int] -> [Int]
Връща нов списък с елементите от първия в обратен ред.
> reverse [1, 2, 3]
[3, 2, 1]
concat :: [[Int]] -> [Int]
"Опростява" списък от списъци до списък, като слепва вложените списъци.
> concat []
[]
> concat [[1, 2, 3], [4, 5, 6]]
[1, 2, 3, 4, 5, 6]
replicate :: Int -> Int -> [Int]
Създава списък от даден елемент x
повторен n
пъти.
> replicate 1 5
[5]
> replicate 4 1
[1, 1, 1, 1]
interleave :: [Int] -> [Int] -> [Int]
Кръстосва два списъка. Резултатният списък взима елемент първо от първия, после от втория, докато не изчерпи елементите на по-късият списък.
> interleave [1, 2, 3] [4, 5, 6]
[1, 4, 2, 5, 3, 6]
> interleave [1, 2] [3, 4, 5]
[1, 3, 2, 4]
sum :: [Int] -> Int
Връща сумата на числата в подадения списък.
> sum []
0
> sum [1, 2, 3]
6
maximum :: [Int] -> Int
Връща стойността на най-голямото число в списъка.
> maximum [1, 2, 3]
3
> maximum []
** Exception: empty list
nub :: [Int] -> [Int]
Премахва повтарящите се елементи от подадения списък.
> Data.List.sort (nub [1, 2, 3, 2, 4])
[1, 2, 3, 4]
> Data.List.sort (nub [])
[]
delete :: Int -> [Int] -> [Int]
Премахва първото срещане на подадения елемент от списъка.
> delete 2 [1, 2, 2, 3, 4]
[1, 2, 3, 4]
> delete 5 [1, 2, 3, 4]
[1, 2, 3, 4]
difference :: [Int] -> [Int] -> [Int]
Връща всички елементи от първия списък xs
, които не са налични във втория ys
.
ВАЖНО: Двата списъка не са стриктно множества
, a могат да имат и повтарящи се елементи. В такъв случай, ако елемента x
се повтаря n
пъти в xs
, то в резултата x
трябва да присъства n - m
пъти, където m
е срещанията на x
в ys
.
> difference [1, 2, 3] [1, 2]
[3]
> difference [1, 2, 2, 2, 3, 4] [1, 2, 2, 3, 3]
[2, 4]
union :: [Int] -> [Int] -> [Int]
Връща всички елементи на първия списък xs
, като към тях са добавени и елементите на втория ys
, които xs
не съдържа.
ВАЖНО: Ако има повторения на елементи в xs
, те присъстват в изхода непроменени. Ако има повторения в ys
те се добавят еднократно към резултата.
> Data.List.sort (union [1, 2, 3] [1, 2, 3, 4])
[1, 2, 3, 4]
> Data.List.sort (union [1, 2, 2] [3, 3])
[1, 2, 2, 3]
intersect :: [Int] -> [Int] -> [Int]
Връща всички елементи от първия списък xs
, които са налични и във втория ys
.
ВАЖНО: Ако даден елемент в xs
се повтаря и е също наличен в ys
, то той се повтаря и в изхода.
> intersect [1, 2, 3] [1, 2, 3, 4]
[1, 2, 3]
> intersect [1, 2, 2] [2, 3]
[2, 2]