Haskell Moduły Moduł zestaw powiązanych funkcji, typów, typeclass. Program w Haskellu często jest modułem, który ładuje inne moduły a następnie wykorzystuje zdefiniowane w nich funkcje w celu realizacji postawionego zadania. Haskell dostarcza w postaci modułów bibliotekę funkcji pozwalających np. na: operacje na liczbach zespolonych, operacje na listach, programowanie współbieżne itp. Domyślnie importowany jest moduł Prelude, z którego dotychczas korzystaliśmy.
Haskell Moduły Ładowanie Załadowanie modułu: np.: import <nazwa modułu> import Data.List Od tego momentu exportowane przez Data.List funkcje itp. są dostępne. Np.: import Data.List numuniques :: (Eq a) => [a] > Int numuniques = length. nub
Haskell Moduły Ładowanie Używając ghci można załadować moduł poprzez: ghci > :m + Data.List Można również załadować jednocześnie wiele modułów: ghci > :m + Data.List Data.Map Data.Set Funkcje eksportowane przez załadowane w ten sposób moduły dostępne są w globalnej przestrzeni nazw tzn. można się do nich odwoływać przez ich nazwy.
Haskell Moduły Ładowanie W przypadku potrzeby użycia tylko kilku z funkcji eksportowanych przez moduł możn użyć formy: import Data.List (nub, sort) Spowoduje to, że funkcji nub i sort z modułu Data.List będą dostępne w globalnej przestrzeni nazw. Inną możliwością jest użycie wszystkich funkcji modułu z wyjątkiem wymienionych: import Data.List hiding (nub) W tym przypadku funkcja nub nie będzie dostępna w globalnej przestrzeni nazw.
Haskell Moduły Ładowanie Użycie formy: import qualified Data.Map Spowoduje, że użycie funkcji eksportowanej przez moduł będzie wymagało wyspecyfikowanie nazwy kwalifikowanej np.: Data.Map.filter Użycie konstrukcji: import qualified Data.Map as M daje możliwość skrócenia zapisu do: M.filter
Haskell Moduły Przydatne moduły: Data.List operacje na listach Data.Char operacje na znakach Data.Map operacje na tablicach asocjacyjnych Data.Set operacje na zbiorach
Haskell Moduły - Pomoc Aby wyświetlić listę funkcji eksportowanych przez moduł: Prelude> :browse Data.List Można również zastosować: Prelude> :m +Data.List Prelude Data.List> Data.List.<TAB> Display all 112 possibilities? (y or n) Data.List.!! Data.List.mapAccumR Data.List.++ Data.List.maximum Data.List.\\ Data.List.maximumBy Data.List.foldr1 Data.List.tails Data.List.genericDrop Data.List.take Data.List.genericIndex Data.List.takeWhile
Haskell Moduł Data.List Przykładowe funkcje; transpose transpozycja listy list ghci > transpose [[1,2,3],[4,5,6], [7,8,9]] [[1,4,7],[2,5,8],[3,6,9]] ghci > transpose ["hey","there","guys"] ["htg","ehu","yey","rs","e"]
Haskell Moduł Data.List concat zamiany listy list na listę ghci > concat ["foo","bar","car"] "foobarcar" ghci > concat [[3,4,5],[2,3,4], [2,1,1]] [3,4,5,2,3,4,2,1,1]
Haskell Moduł Data.List and przyjmuje listę wartości logicznych jako argument i zwraca True jeśli wszystkie wartości na liście mają wartość True ghci > and $ map (>4) [5,6,7,8] True ghci > and $ map (==4) [4,4,4,3,4] False Podobnie działa or.
Haskell Moduł Data.List Zamiast or i and w połączniu z map można użyć odpowiednio any i all: ghci > any (==4) [2,3,5,6,1,4] True ghci > all (>4) [6,9,10] True ghci > all (`elem ` ['A'..'Z']) "HEYGUYSwhatsup" False ghci > any (`elem ` ['A'..'Z']) "HEYGUYSwhatsup" True
Haskell Moduł Data.List iterate przyjmuje jako argument funkcję i wartość startową a następnie przykłada funkcję do wartości startowej po czym do wyniku przykłada funkcję, po czym do wyniku przykłada funkcję itd. Wszystkie wyniki zwraca jako listę nieskończoną: ghci > take 10 $ iterate (*2) 1 [1,2,4,8,16,32,64,128,256,512] ghci > take 3 $ iterate (++ "haha") "haha" ["haha","hahahaha","hahahahahaha"]
Haskell Moduł Data.List sort sortuje listę elementów typeclass Ord: ghci > sort [8,5,3,2,1,6,4,2] [1,2,2,3,4,5,6,8] ghci > sort "This will be sorted soon" " Tbdeehiillnooorssstw"
Haskell Moduł Data.List words dzieli linię tekstu na słowa a unwords tworzy linię tekstu z listy słów: ghci > words "hey these are the words in this sentence" ["hey","these","are","the","words","in","this","sentenc e"] ghci > words "hey these are the words in this\nsentence" ["hey","these","are","the","words","in","this","sentenc e"] ghci > unwords ["hey","there","mate"] "hey there mate"
Haskell Moduł Data.List nub usuwa z listy duplikaty elementów listy: ghci > nub [1,2,3,4,3,2,1,2,3,4,3,2,1] [1,2,3,4] ghci > nub "Lots of words and stuff" "Lots fwrdanu"
Haskell Moduł Data.Char Moduł Data.Char zawiera funkcje do operowania na pojedynczych znakach np.: IsAlphaNum zwraca True jeśli argument jest znakiem alfanumerycznym lub False w przeciwnym przypadku: ghci > all isalphanum "bobby283" True ghci > all isalphanum "eddy the fish!" False
Haskell Moduł Data.Char Data.Char dostarcza m.in. funkcje toupper i tolower a także digittoint i inttodigit: ghci > map digittoint "34538" [3,4,5,3,8] ghci > map digittoint "FF85AB" [15,15,8,5,10,11] ghci > inttodigit 15 'f' ghci > inttodigit 5 '5'
Haskell Moduł Data.Map Moduł Data.Map dostarcza funkcji do przeprowadzania operacji na tablicach asocjacyjnych. Tablice asocjacyjne mogą być reprezentowane jako lista krotek: phonebook = [("betty","555 2938"),("bonnie","452 2928"),("patsy","493 2928"),("lucille","205 2928"),("wendy","939 8282"),("penny","853 2492") ]
Haskell Moduł Data.Map W module Data.Map używany jest typ Map. Zmienne tego typu można utworzyć np.: Prelude M> let lista = M.fromList [("Zed", 10), ("Ted", 5)] Prelude M> :t lista lista :: M.Map [Char] Integer
Haskell Moduł Data.Map empty zwraca pustą mapę insert przyjmuje jako parametr klucz, wartość i mapę i zwraca nową mapę z wstawionym kluczem i wartością: ghci > Map.empty fromlist [] ghci > Map.insert 3 100 Map.empty fromlist [(3,100)]
Haskell Moduł Data.Map lookup przyjmuje jako argument klucz i listę i zwraca Just wartość jeżeli dla klucza istnieje wartość lub Nothing jeżeli nie znajdzie klucza. Prelude M> M.lookup "Ted" lista Just 5 member jako argumenty przyjmuje klucz i mapę i zwraca informację czy dla klucza istnieje wartość: ghci > Map.member 3 $ Map.fromList [(3,6),(4,3),(6,9)] True ghci > Map.member 3 $ Map.fromList [(2,5),(4,5)] False
Haskell Moduł Data.Set Moduł Data.Set oferuje operacje na zbiorach. Zbiory podobnie jak mapy tworzone są z list np.: Prelude> import qualified Data.Set as Set Prelude Set> let seta = Set.fromList [ 1, 2, 3] Prelude Set> let setb = Set.fromList [ 3, 4, 5] Prelude Set> :t seta seta :: Set.Set Integer
Haskell Moduł Data.Set Na zbiorach możliwe są typowe dla zbiorów operacje jak intersection, difference: Prelude Set> Set.intersection seta setb fromlist [3] Prelude Set> Set.difference seta setb FromList [1,2] Prelude Set> Set.union seta setb fromlist [1,2,3,4,5]
Haskell Moduły Tworzenie Aby utworzyć własny moduł np. zawierajacy funkcje zwiazane z geometrią należy utworzyć plik.hs (np.: Geometry.hs) zawierający nagłowek opisujący jakie funkcje moduł eksportuje (udostępnia): module Geometry ( spherevolume, spherearea, cubevolume ) where
Haskell Moduły Tworzenie Po czym następują definicje funkcji np.: spherevolume :: Float > Float spherevolume radius = (4.0 / 3.0) * pi * (radius ^ 3) spherearea :: Float > Float spherearea radius = 4 * pi * (radius ^ 2)
Haskell Moduły Tworzenie Własnego modułu można użyć tak jak modułów dostarczanych standardowo: ghci> import Geometry
Haskell Moduły Tworzenie Moduły mogą być tworzone jako konstrukcje hierarchiczne. Każdy moduł może zawierać podmoduły. Moduł Geometry może zostać przedstawiony jako zawierający podmoduły dla różnych rodzajów obiektów. Należy utworzyć katalog Geometry zawierający pliki sphere.hs, cuboid.hs and cube.hs.
Haskell Moduły Tworzenie sphere.hs module Geometry.Sphere ( volume, area ) where volume :: Float > Float volume radius = (4.0 / 3.0) * pi * (radius ^ 3) area :: Float > Float area radius = 4 * pi * (radius ^ 2)
Haskell Moduły Tworzenie cuboid.hs module Geometry.Cuboid ( volume, area ) where volume :: Float > Float > Float > Float volume a b c = rectanglearea a b * c area :: Float > Float > Float > Float area a b c = rectanglearea a b * 2 + rectanglearea a c * 2 + rectanglearea c b * 2 rectanglearea :: Float > Float > Float rectanglearea a b = a * b
Haskell Moduły Tworzenie cube.hs module Geometry.Cube ( volume, area ) where import qualified Geometry.Cuboid as Cuboid volume :: Float > Float volume side = Cuboid.volume side side side area :: Float > Float area side = Cuboid.area side side side
Haskell Moduły Tworzenie Użycie takiego modułu: import Geometry.Sphere Teraz można użyć area i volume do wyliczenia pola i objętości kuli. Można również wykonać: import qualified Geometry.Sphere as Sphere import qualified Geometry.Cuboid as Cuboid import qualified Geometry.Cube as Cube Można wtedy wywołać: Sphere.area, Sphere.volume itd. do obliczenia pola powierzchni i objętości odpowiednich obiektów.