TWORZENIE SWOICH TYPÓW I TYPÓW KLAS HASKELL (RODZIAŁ 8) ZAJĘCIA 4

Podobne dokumenty
ROZDZIAŁ 8: KLASY TYPÓW

WEJŚCIE/WYJŚCIE HASKELL ŁUKASZ PAWLAK DARIUSZ KRYSIAK

Tworzenie własnych typów. danych oraz klas typów

Zatem w jaki sposób nasze programy mają komunikować się ze światem zewnętrznym?

Haskell Moduły Ładowanie

Haskell Input and Output Źródło:

- nawiasy kwadratowe oznaczają, że to lista

Elementy języka Haskell

Języki programowania Haskell

PARADYGMATY I JĘZYKI PROGRAMOWANIA. Haskell. (w11)

Programowanie w języku Haskell

Leży u podstaw programowania funkcyjnego. Napisy. 1 Zastapienie dowolnego wyrażenia innym wyrażeniem o tej samej. wartości daje równoważny program.

Paradygmaty programowania

Programowanie w języku Haskell

Prezentacja o Haskell u(rozdział 3 i 4)

Programowanie w języku Haskell

Języki i Paradygmaty Programowania

Programowanie Komputerów

Język ludzki kod maszynowy

W powyższym kodzie utworzono wyliczenie dni tygodnia.

Typy, klasy typów, składnie w funkcji

Programowanie obiektowe

Laboratorium 1 - Programowanie proceduralne i obiektowe

Moduły. Źródło: a) Wczytywanie modułów. interparse rozdziela każdy element listy wcześniej podanym znakiem

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

Podstawy programowania, Poniedziałek , 8-10 Projekt, część 1

Wstęp do Programowania potok funkcyjny

Zajęcia nr 2 Programowanie strukturalne. dr inż. Łukasz Graczykowski mgr inż. Leszek Kosarzewski Wydział Fizyki Politechniki Warszawskiej

Definicje wyższego poziomu

Kurs programowania. Wykład 9. Wojciech Macyna. 28 kwiecień 2016

Wstęp do programowania INP001213Wcl rok akademicki 2017/18 semestr zimowy. Wykład 12. Karol Tarnowski A-1 p.

Programowanie. Lista zadań nr 15. Na ćwiczenia 11, 19 i 23 czerwca 2008

Programowanie obiektowe

Operatory cd. Relacyjne: ==!= < > <= >= bool b; int i =10, j =20; dzielenie całkowitych wynik jest całkowity! Łączenie tekstu: + string s = "Ala ma ";

Podstawowe elementy proceduralne w C++ Program i wyjście. Zmienne i arytmetyka. Wskaźniki i tablice. Testy i pętle. Funkcje.

C++ wprowadzanie zmiennych

Podstawy języka C++ Maciej Trzebiński. Instytut Fizyki Jądrowej Polskiej Akademii Nauk. Praktyki studenckie na LHC IVedycja,2016r.

Java Programowanie Obiektowe Ćwiczenie 1- wprowadzenie

Programowanie funkcyjne (Haskell Wprowadzenie) Kowalik Adrian

Technologie cyfrowe semestr letni 2018/2019

WSNHiD, Programowanie 2 Lab. 2 Język Java struktura programu, dziedziczenie, abstrakcja, polimorfizm, interfejsy

Podstawowe części projektu w Javie

Bash - wprowadzenie. Bash - wprowadzenie 1/39

Wstęp do programowania 2

Dariusz Brzeziński. Politechnika Poznańska, Instytut Informatyki

Programowanie w języku Python. Grażyna Koba

MATERIAŁY DO ZAJĘĆ II

Programowanie funkcyjne wprowadzenie Specyfikacje formalne i programy funkcyjne

Podstawy Programowania Podstawowa składnia języka C++

IMIĘ i NAZWISKO: Pytania i (przykładowe) Odpowiedzi

Programowanie w C++ Wykład 8. Katarzyna Grzelak. 15 kwietnia K.Grzelak (Wykład 8) Programowanie w C++ 1 / 33

Typy złożone. Struktury, pola bitowe i unie. Programowanie Proceduralne 1

Microsoft IT Academy kurs programowania

Obiektowy Caml. Paweł Boguszewski

Wstęp do Programowania potok funkcyjny

Podstawy i języki programowania

JAVA W SUPER EXPRESOWEJ PIGUŁCE

Temat: Dynamiczne przydzielanie i zwalnianie pamięci. Struktura listy operacje wstawiania, wyszukiwania oraz usuwania danych.

Języki i metodyka programowania. Typy, operatory, wyrażenia. Wejście i wyjście.

Podstawy języka C++ Maciej Trzebiński. Praktyki studenckie na LHC IFJ PAN. Instytut Fizyki Jądrowej Polskiej Akademii Nauk. M. Trzebiński C++ 1/16

Wykład II. Programowanie II - semestr II Kierunek Informatyka. dr inż. Janusz Słupik. Wydział Matematyki Stosowanej Politechniki Śląskiej

Wstęp do wiadomości teoretycznych (nie, nie jest to masło maślane ani wstęp, wstępów proszę cierpliwie czytać)

PARADYGMATY PROGRAMOWANIA Wykład 4

Język C++ wykład VIII

Programowanie strukturalne. Opis ogólny programu w Turbo Pascalu

Wprowadzenie do języka Java

Wstęp do Programowania, laboratorium 02

Wprowadzenie do programowania w języku Visual Basic. Podstawowe instrukcje języka

Pliki w C/C++ Przykłady na podstawie materiałów dr T. Jeleniewskiego

Podstawy Programowania C++

Programowanie obiektowe

- Narzędzie Windows Forms. - Przykładowe aplikacje. Wyższa Metody Szkoła programowania Techniczno Ekonomiczna 1 w Świdnicy

Dokumentacja do API Javy.

Kurs rozszerzony języka Python

Technologie cyfrowe semestr letni 2018/2019

Python. Wprowadzenie. Jolanta Bachan

Funkcje w PL/SQL Funkcja to nazwany blok języka PL/SQL. Jest przechowywana w bazie i musi zwracać wynik. Z reguły, funkcji utworzonych w PL/SQL-u

Programowanie w C++ Wykład 9. Katarzyna Grzelak. 14 maja K.Grzelak (Wykład 9) Programowanie w C++ 1 / 30

Szablony klas, zastosowanie szablonów w programach

Obliczenia, zmienne. Proste działania, zmienne, rodzaje zmiennych, proste operacje i działania na zmiennych.

Wykład 4: Klasy i Metody

4. Funkcje. Przykłady

Kurs programowania. Wykład 9. Wojciech Macyna

Programowanie proceduralne INP001210WL rok akademicki 2018/19 semestr letni. Wykład 6. Karol Tarnowski A-1 p.

Struktury, unie, formatowanie, wskaźniki

Swift (pol. jerzyk) nowy język programowania zaprezentowany latem 2014 r. (prace od 2010 r.)

KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany

Programowanie - instrukcje sterujące

Programowanie I C / C++ laboratorium 03 arytmetyka, operatory

Wstęp do Programowania potok funkcyjny

Test przykładowy 2 PAI WSB Wrocław /06/2018

Programowanie Komputerów

5 Przygotował: mgr inż. Maciej Lasota

Przydatne sztuczki - sql. Na przykładzie postgres a.

Podstawy programowania

Wstęp do informatyki. stęp do informatyki Polecenia (cz.2)

Informatyka I. Typy danych. Operacje arytmetyczne. Konwersje typów. Zmienne. Wczytywanie danych z klawiatury. dr hab. inż. Andrzej Czerepicki

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

Laboratorium 03: Podstawowe konstrukcje w języku Java [2h]

utworz tworzącą w pamięci dynamicznej tablicę dwuwymiarową liczb rzeczywistych, a następnie zerującą jej wszystkie elementy,

Transkrypt:

TWORZENIE SWOICH TYPÓW I TYPÓW KLAS HASKELL (RODZIAŁ 8) ZAJĘCIA 4

Wprowadzenie do typów algebraicznych

WPROWADZENIE DO TYPÓW ALGEBRAICZNYCH Słowo data oznacza zdefiniowanie nowego typu danych Typ Bool ze standardowej biblioteki wygląda następująco data Bool = False True (przyjmuje wartości False lub True) Typ Int ze standardowej biblioteki wygląda następująco data Int = -2147483648-2147483647... -1 0 1 2... 2147483647 (przyjmuje wszystkie liczby całkowite od -2147483648 do 2147483647

NOWE WŁASNE TYPY DANYCH Chcemy stworzyć typ kształt, który może być kołem lub prostokątem data Shape = Circle Float Float Float Rectangle Float Float Float Float Typ Circle przyjmuje współrzędną X oraz Y środka koła oraz promień, a typ Rectangle współrzędne X oraz Y lewego górnego rogu prostokąta oraz współrzędne X i Y prawego dolnego rogu prostokąta. Jeśli chcemy wyświetlić parametry typu to musimy wypisać :t naz_typ ghci > :t Circle Circle :: Float -> Float -> Float -> Shape ghci > :t Rectangle Rectangle :: Float -> Float -> Float -> Float -> Shape

FUNKCJA: POWIERZCHNIA KSZTAŁTU (1) Teraz wykorzystamy nowo utworzony typ Shape do stworzenia funkcji, która obliczy polę powierzchni kształtu (koła lub prostokątu) data Shape = Circle Float Float Float Rectangle Float Float Float Float surface :: Shape -> Float surface ( Circle r) = pi * r ^ 2 surface ( Rectangle x1 y1 x2 y2) = (abs $ x2 - x1) * ( abs $ y2 - y1) Wywołanie i rezultat funkcji w programie ghci > surface $ Circle 10 20 10 314.15927 ghci > surface $ Rectangle 0 0 100 100 10000.0

WYŚWIETLENIE TYPU Z PODANYMI PARAMETRAMI Co wpisać, żeby program wyświetlił typ oraz parametry jakie do niego dodaliśmy. data Shape = Circle Float Float Float Rectangle Float Float Float Float deriving ( Show ) Słowo derivering ( Show ), który jest na końcu deklaracji typu danych oznacza, że program wyświetli na ekran typ i podane parametry np. ghci > Circle 10 20 5 Circle 10.0 20.0 5.0 ghci > Rectangle 50 230 60 90 Rectangle 50.0 230.0 60.0 90.0

MAPOWANIE TYPÓW Chcemy wyświetlić parametry dla koła o współrzędnych X = 10 oraz Y = 20 dla różnych promieni, które są w liście. ghci > map ( Circle 10 20) [4,5,6,6] [ Circle 10.0 20.0 4.0, Circle 10.0 20.0 5.0, Circle 10.0 20.0 6.0, Circle 10.0 20.0 6.0]

FUNKCJA: POWIERZCHNIA KSZTAŁTU (2) Powracamy do funkcji, która liczy pole powierzchni kształtu tym razem zamiast dwukrotnie przyjmować Float może przyjąć Point, który składa się z dwóch Float ów. data Point = Point Float Float deriving ( Show ) data Shape = Circle Point Float Rectangle Point Point deriving ( Show ) ghci > surface ( Rectangle ( Point 0 0) ( Point 100 100)) 10000.0 ghci > surface ( Circle ( Point 0 0) 24) 1809.5574 Wywołanie: ghci > surface ( Rectangle ( Point 0 0) ( Point 100 100)) 10000.0 ghci > surface ( Circle ( Point 0 0) 24) 1809.5574

FUNKCJA, KTÓRA PRZESUWA KSZTAŁT nudge :: Shape -> Float -> Float -> Shape nudge ( Circle ( Point x y) r) a b = Circle ( Point (x+a) (y+b)) r nudge ( Rectangle ( Point x1 y1) ( Point x2 y2 )) a b = Rectangle ( Point (x1+a) (y1+b)) ( Point (x2+a) (y2+b)) ghci > nudge ( Circle ( Point 34 34) 10) 5 10 Circle ( Point 39.0 44.0) 10.0 basecircle :: Float -> Shape basecircle r = Circle ( Point 0 0) r baserect :: Float -> Float -> Shape baserect width height = Rectangle ( Point 0 0) ( Point width height ) ghci > nudge ( baserect 40 100) 60 23 Rectangle ( Point 60.0 23.0) ( Point 100.0 123.0)

EKSPORTOWANIE TYPÓW W MODUŁACH module Shapes ( Point (..), Shape (..), surface, nudge, basecircle, baserect ) where By doing Shape(..), we exported all the value constructors for Shape, so that means that whoever imports our module can make shapes by using the Rectangle and Circle value constructors. It s the same as writing Shape (Rectangle, Circle).

Składnia rekordu

REKORD PERSON Chcemy stworzyć rekord Person, który zawiera takie pola jak: first name (imię), last name (nazwisko), age (wiek), height (wrost), phone numer (numer telefonów), and favorite ice-cream flavor (ulubiony smak). data Person = Person String String Int Float String String deriving ( Show ) ghci >let osoba = Person " Stefan " " Kasztaniak " 33 188.2 " 526-2928 " " Strawberry ghci > osoba Person " Stefan " " Kasztaniak " 33 188.2 " 526-2928 " " Strawberry

REKORD PERSON Składanie rekordu z poszczególnych składowych data Person = Person { firstname :: String, lastname :: String, age :: Int, height :: Float, phonenumber :: String, flavor :: String } deriving ( Show ) Zwrócenie imienia zmiennej osoba ghci > firstname osoba Stefan Po skompilowaniu rekordu Haskell tworzy automatycznie typ danych dla poszczególnych składowych rekordu ghci > :t firstname firstname :: Person -> String

RODZAJE PARAMETRÓW Rodzaje parametrów

TYP MAYBE (SZABLONY) data Maybe a = Nothing Just a ghci > Just " Haha Just " Haha " ghci > Just 84 Just 84 ghci > :t Just " Haha Just " Haha " :: Maybe [ Char ] ghci > :t Just 84 Just 84 :: ( Num t) => Maybe t ghci > :t Nothing Nothing :: Maybe a ghci > Just 10 :: Maybe Double Just 10.0 Słowo Maybe oznacza, że prawdopodobnie zostanie zwrócony typ, o który prosimy (jeśli jest) albo może być zwrócona wartośćpusta (Nothing)

REKORD CAR data Car a b c = Car { company :: a, model :: b, year :: c } deriving ( Show ) Zamiast String, String, Int podajemy a, b, c, ponieważ przy wywołaniu rekordu za pomocą słowa Maybe można nadać inny typ dla któreś ze składowych.

FUNKCJA WYŚWIETLAJĄCA INFORMACJE O REKORDZIE CAR tellcar :: Car -> String tellcar ( C ghci > let stang = Car { company =" Ford ", model =" Mustang ", year =1967} ghci > tellcar stang " This Ford Mustang was made in 1967 tellcar :: ( Show a) => Car String String a -> String tellcar ( Car { company = c, model = m, year = y}) = " This " ++ c ++ " " ++ m ++ " was made in " ++ show y ghci > tellcar ( Car " Ford " " Mustang " 1967) " This Ford Mustang was made in 1967 " ghci > tellcar ( Car " Ford " " Mustang " " nineteen sixty seven ") " This Ford Mustang was made in \" nineteen sixty seven \"" ghci > :t Car " Ford " " Mustang " 1967 Car " Ford " " Mustang " 1967 :: ( Num t) => Car [ Char ] [ Char ] t ghci > :t Car " Ford " " Mustang " " nineteen sixty seven Car " Ford " " Mustang " " nineteen sixty seven " :: Car [ Char ] [ Char ] [ Char ]

OPERACJE NA WEKTORACH data Vector a = Vector a a a deriving ( Show ) vplus :: ( Num t) => Vector t -> Vector t -> Vector t ( Vector i j k) `vplus ` ( Vector l m n) = Vector (i+l) (j+m) (k+n) vectmult :: ( Num t) => Vector t -> t -> Vector t ( Vector i j k) `vectmult ` m = Vector (i*m) (j*m) (k*m) scalarmult :: ( Num t) => Vector t -> Vector t -> t ( Vector i j k) `scalarmult ` ( Vector l m n) = i*l + j*m + k*n Wywołanie operacji opartych na wektorach ghci > Vector 3 5 8 `vplus ` Vector 9 2 8 Vector 12 7 16 ghci > Vector 3 5 8 `vplus ` Vector 9 2 8 `vplus ` Vector 0 2 3 Vector 12 9 19 ghci > Vector 3 9 7 `vectmult ` 10 Vector 30 90 70 ghci > Vector 4 9 5 `scalarmult ` Vector 9.0 2.0 4.0 74.0 ghci > Vector 2 9 3 `vectmult ` ( Vector 4 9 5 `scalarmult ` Vector 9 2 4) Vector 148 666 222

Derived instances

PRZYRÓWNANIE KLAS data Person = Person { firstname :: String, lastname :: String, age :: Int } deriving (Eq) ghci > let miked = Person { firstname = " Michael ", lastname = " Diamond ", age = 43} ghci > let adrock = Person { firstname = " Adam ", lastname = " Horovitz ", age = 41} ghci > let mca = Person { firstname = " Adam ", lastname = " Yauch ", age = 44} ghci > mca == adrock False ghci > miked == adrock False ghci > miked == miked True ghci > miked == Person { firstname = " Michael ", lastname = " Diamond ", age = 43} True ghci > let beastieboys = [mca, adrock, miked ] ghci > miked `elem ` beastieboys True

PRZYRÓWNANIE, WYSWIETLENIE, CZYTANIE REKORDU data Person = Person { firstname :: String, lastname :: String, age :: Int } deriving (Eq, Show, Read ) ghci > let miked = Person { firstname = " Michael ", lastname = " Diamond ", age = 43} ghci > miked Person { firstname = " Michael ", lastname = " Diamond ", age = 43} ghci > " miked is: " ++ show miked " miked is: Person { firstname = \" Michael \", lastname = \" Diamond \", age = 43} read " Person { firstname =\" Michael \", lastname =\" Diamond \", age = 43} :: Person Person { firstname = " Michael ", lastname = " Diamond ", age = 43} ghci > read " Person { firstname =\" Michael \", lastname =\" Diamond \", age = 43}"== miked True

MODYFIKACJA TYPU BOOL data Bool = False True deriving (Ord) ghci > Nothing < Just 100 True ghci > Nothing > Just ( -49999) False ghci > Just 3 `compare ` Just 2 GT ghci > Just 100 > Just 50 True

DNI TYGODNIA data Day = Monday Tuesday Wednesday Thursday Friday Saturday Sunday deriving (Eq, Ord, Show, Read, Bounded, Enum ) ghci > Wednesday Wednesday ghci > show Wednesday " Wednesday " ghci > read " Saturday " :: Day Saturday ghci > Saturday > Friday True ghci > Monday `compare ` Wednesday LT

DNI TYGODNIA PRZYKŁADOWE OPERACJE ghci > succ Monday Tuesday ghci > pred Saturday Friday ghci > [ Thursday.. Sunday ] [ Thursday, Friday, Saturday, Sunday ] ghci > [ minbound.. maxbound ] :: [Day] [ Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday ]

Rodzaje synonimów

TYPY SYNONINÓW type String = [ Char ] type IntMap v = Map Int v

EITHER data Either a b = Left a Right b deriving (Eq, Ord, Read, Show ) ghci > Right 20 Right 20 ghci > Left " w00t Left " w00t ghci > :t Right 'a Right 'a' :: Either a Char ghci > :t Left True Left True :: Either Bool b

FUNKCJE WYKORZYSTUJĄCE EITHER import qualified Data. Map as Map data LockerState = Taken Free deriving (Show, Eq) type Code = String type LockerMap = Map. Map Int ( LockerState, Code ) lockerlookup :: Int -> LockerMap -> Either String Code oraz lockers :: LockerMap znajdują się w pliku Synonims.hs ghci > lockerlookup 101 lockers Right " JAH3I ghci > lockerlookup 100 lockers Left " Locker 100 is already taken! ghci > lockerlookup 102 lockers Left " Locker number 102 doesn 't exist! ghci > lockerlookup 110 lockers Left " Locker 110 is already taken! ghci > lockerlookup 105 lockers Right " QOTSA "

Rekurencyjne struktury danych

NASZA LISTA Podział listy na head oraz tail data List a = Empty Cons { listhead :: a, listtail :: List a} deriving (Show, Read, Eq, Ord ) ghci > 3 `Cons ` (4 `Cons ` (5 `Cons ` Empty )) Cons 3 ( Cons 4 ( Cons 5 Empty )) ghci > Empty Empty Inny zapis listy z podziałem na head oraz tail to: infixr 5 :-: data List a = Empty a :-: ( List a) deriving (Show, Read, Eq, Ord ) ghci > let a = 3 :-: 4 :-: 5 :-: Empty ghci > 100 :-: a (: -:) 100 ((: -:) 3 ((: -:) 4 ((: -:) 5 Empty )))

ŁĄCZENIE NASZYCH LIST infixr 5.++ (.++) :: List a -> List a -> List a Empty.++ ys = ys (x :-: xs).++ ys = x :-: (xs.++ ys) ghci > let a = 3 :-: 4 :-: 5 :-: Empty ghci > let b = 6 :-: 7 :-: Empty ghci > a.++ b (: -:) 3 ((: -:) 4 ((: -:) 5 ((: -:) 6 ((: -:) 7 Empty ))))

DRZEWA data Tree a = EmptyTree Node a ( Tree a) ( Tree a) deriving (Show, Read, Eq) treeelem :: ( Ord a) => a -> Tree a -> Bool treeelem x EmptyTree = False treeelem x ( Node a left right ) x == a = True x < a = treeelem x left x > a = treeelem x right Więcej informacji w pliku drzewa.hs ghci > let nums = [8,6,4,1,7,3,5] ghci > let numstree = foldr treeinsert EmptyTree nums ghci > 1 `treeelem ` numstree True ghci > 10 `treeelem ` numstree False foldr, treeinsert są to funkcje, które pobierają listę i tworzą z tego drzewo

Typeclasses 102

KLASA I INSTANCJA Klasa Eq ze standardowej biblioteki class Eq a where (==) :: a -> a -> Bool (/=) :: a -> a -> Bool x == y = not (x /= y) x /= y = not (x == y) Nowa klasa TrafficLight data TrafficLight = Red Yellow Green instance Eq TrafficLight where Red == Red = True Green == Green = True Yellow == Yellow = True _ == _ = False ghci > Red == Red True ghci > Red == Yellow False ghci > Red `elem ` [Red, Yellow, Green ] True ghci > [Red, Yellow, Green ] [ Red light, Yellow light, Green light ]

KLASA I INSTANCJA + MAYBE instance (Eq m) => Eq ( Maybe m) where Just x == Just y = x == y Nothing == Nothing = True _ == _ = False Użycie niektórych różnych od siebie typów może spowodować wyjątki

A yes-no typeclass

KLASA YES-NO Ta klasa sprawdza czy istnieje wartość i zwraca tylko Prawdę lub Fałsz Instancja klasy YesNo może być zadeklarowana dla różnych typów (listy, Bool, Int itd.) class YesNo a where yesno :: a -> Bool instance YesNo [a] where yesno [] = False yesno _ = True yesnoif :: ( YesNo y) => y -> a -> a -> a yesnoif yesnoval yesresult noresult = if yesno yesnoval then yesresult else noresult Rezultat: ghci > yesnoif [] " TAK! "NIE! NIE! ghci > yesnoif [2,3,4] " TAK!" "NIE! " TAK!"

Funktor typów klas

FUNKTOR MNOŻENIE ELEMENTÓW Z LISTY class Functor f where fmap :: (a -> b) -> f a -> f b instance Functor [] where fmap = map ghci > fmap (*5) [1..11] [5,10,15,20,25,30,35,40,45,50,55]

FUNKTOR + MAYBE instance Functor Maybe where fmap f ( Just x) = Just (f x) fmap f Nothing = Nothing ghci > fmap (*7) ( Just 100) Just 700 Funktor można zastosować również na swoich instancjach np. na Tree

FUNKTOR (EITHER) Deklaracja: data Either a b = Left a Right b Zwraca lewy lub prawy element instance Functor ( Either a) where fmap f ( Right x) = Right (f x) fmap f ( Left x) = Left x

Rodzaje i niektóre type-foo

RODZAJE I NIEKTÓRE TYPE-FOO * oznacza konkretny typ ghci > :k Int Int :: * ghci > :k Maybe Maybe :: * -> * ghci > :k Maybe Int Maybe Int :: * ghci > :k Either String Either String :: * -> * ghci > :k Either String Int Either String Int :: *

WŁASNY TYP DANYCH class Tofu t where tofu :: j a -> t a j data Frank a b = Frank { frankfield :: b a} deriving ( Show ) ghci > :t Frank { frankfield = " TAK "} Frank { frankfield = " TAK "} :: Frank Char [] instance Tofu Frank where tofu x = Frank x ghci > tofu [" HELLO "] :: Frank [ Char ] [] Frank { frankfield = [" HELLO "]}

FUNKTOR :k Frank Frank :: * -> (* -> *) -> * data Barry t k p = Barry { val1 :: p, val2 :: t k } instance Functor ( Barry a b) where fmap f ( Barry { val1 = x, val2 = y}) = Barry { val1 = f x, val2 = y}

HASKELL Input / Output 1

Akcje I/O a funkcje Funkcja dla określonych danych wejściowych zawsze zwraca taki sam wynik. Akcja I/O może dawać różne rezultaty. Po wykonaniu akcji nie uzyskujemy bezpośrednio oczekiwanego wyniku. 2

> :t putstrln putstrln :: String -> IO () > :t getline getline :: IO String 3

tmp = "Witaj, " ++ getline WYGENERUJE BŁĄD 4

main = do putstrln "Podaj swoje imię:" name <- getline putstrln ("Witaj, " ++ name ++ "!") 5

main = do tmp <- putstrln "Podaj swoje imię:" name <- getline putstrln ("Witaj, " ++ name ++ "!") > tmp <- putstrln "Podaj swoje imię:" Podaj swoje imię: > tmp () 6

Ostatniej akcji w bloku do nie można przypisywać do zmiennej. main = do putstrln "Tekst" n <- putstrln "Tekst" wygeneruje błąd kompilacji The last statement in a 'do' block must be an expression n <- putstrln "Tekst" 7

Wywołanie akcji I/O Akcje I/O zostaną wykonane, gdy: otrzymają nazwę main (zostaną poprzedzone: main = ) będą zagnieżdżone wewnątrz innej akcji (poprzez zastosowanie bloku do) zostaną umieszczone w konsoli GHCi, a następnie zatwierdzone klawiszem enter 8

import Data.Char main = do first <- getline let fup = map toupper first let flow = map tolower first putstrln ("Result: " ++ fup ++ " and " ++ flow) 9

main = do line <- getline if null line then return () else do putstrln $ reversewords line main reversewords :: String -> String reversewords = unwords. map reverse. words 10

main = do putstrln "Raz" return () putstrln "Trzy" Po uruchomieniu uzyskamy: Raz Trzy 11

when import Control.Monad if null line then return () else do putstrln $ revw line main możemy zastąpić: when (not $ null line) $ do putstrln (revw line) main 12

Wypisywanie na ekran putstr putstrln putchar print Pobieranie danych getline getchar 13

sequence > s <- sequence [getline, getline, getline] Ala ma kota > s ["Ala","ma","kota"] 14

sequence > sequence (map print [1,2,3]) 1 2 3 [(),(),()] mapm oraz mapm_ sequence (map print [1,2,3,4,5]) da taki sam rezultat, jak: mapm print [1,2,3,4,5] 15

getcontents >:t getcontents IO String interact >:t interact (String String) IO () 16

palindrom = unlines. map (\xs -> if ispalindrome xs then "TAK" else "NIE"). lines where ispalindrome xs = xs == reverse xs main = interact palindrom 17

Operacje na plikach openfile hgetcontents hclose Tryby pracy z plikiem (IOMode): ReadMode WriteMode AppendMode ReadWriteMode 18

import System.IO main = do handle <- openfile "test.txt" ReadMode contents <- hgetcontents handle putstr contents hclose handle 19

Operacje na plikach Alternatywnym sposobem na wykonanie operacji na pliku może być użycie akcji withfile. Uwaga: Po wykonaniu wskazanej funkcji, withfile automatycznie zamknie plik. 20

import System.IO main = do withfile "test.txt" ReadMode (\h -> do contents <- hgetcontents h putstr contents ) 21

Operacje na plikach Standardowe I/O Plik getline hgetline putstr hputstr putstrln hputstrln getchar hgetchar getcontents hgetcontents 22

readfile import System.IO main = do contents <- readfile "test. txt" putstr contents 23

writefile import System.IO main = do writefile "test.txt" "Tekst" appendfile import System.IO main = do appendfile "test.txt" "Tekst" 24

Buforowanie Zmiana sposobu bufrowania: hsetbuffering Tryby buforowania: NoBuffering LineBuffering BlockBuffering BlockBuffering (Just [rozmiar w bajtach]) Opróżnienie bufora: hflush 25

Pliki tymczasowe gettemporarydirectory opentempfile removefile renamefile 26

Przykładowy program z11.hs 27

Argumenty linii poleceń import System.Environment getprogname getargs 28

import System.Environment main = do p <- getprogname args <- getargs putstrln $ "Uruchomiono program " ++ p putstrln "z argumentami:" mapm_ print args > przyklad aaa bbb ccc Uruchomiono program przyklad z argumentami: "aaa" "bbb" "ccc" 29

Wartości pseudolosowe import System.Random Losowanie wartości: random randomr randomr ('a', 'z') (mkstdgen 10) randoms randomrs take 8 $ randomrs (1, 9) (mkstdgen 3) Własny generator: mkstdgen [liczba całkowita] 30

getstdgen import System.Random main = do g <- getstdgen putstr $ take 6 (randomrs ('a','z') g) 31

newstdgen import System.Random main = do g <- getstdgen print $ take 5 (randomrs ('a', 'z') g) g2 <- getstdgen print $ take 5 (randomrs ('a', 'z') g2) gn <- newstdgen print $ take 5 (randomrs ('a', 'z') gn) g3 <- getstdgen print $ take 5 (randomrs ('a', 'z') g3) 32

newstdgen > przyklad_newstdgen "rpyae" "rpyae" "mwyew" "farih" 33

ByteString Strict import Data.ByteString zaleta: złożoność czasowa wady: złożoność pamięciowa niedopuszczalne nieskończone listy Lazy import Data.ByteString.Lazy porcje 64KB złoty środek między odmianą strict a zwykłą listą Zwykła lista zaleta: złożoność pamięciowa wada: złożoność czasowa 34

Operacje na plikach Standardowa lista Plik : ++ cons head head tail tail last last init init null null length length map map append 35

Przykładowy program z17.hs 36

cons oraz cons' Funkcja cons spowoduje, że nowy element będzie umieszczony w nowej porcji, nawet jeśli istniejąca nie jest jeszcze zapełniona. Jeżeli planujemy wielokrotnie zastosować cons, lepiej użyć cons', która zadba o to, by nowa porcja była tworzona tylko wtedy, gdy jest to konieczne. foldr B.cons B.empty [65..68] A B C D foldr B.cons' B.empty [65..68] ABCD 37

pack > import qualified Data.ByteString.Lazy as B > B.pack [65..70] ABCDEF unpack > B.unpack $ B.pack [65..70] [65,66,67,68,69,70] > B.unpack $ B.pack [255,256,257,-6] [255,0,1,250] 38

fromchunks tochunks import qualified Data.ByteString as S import qualified Data.ByteString.Lazy as B main = do let x = B.fromChunks [S.pack [65..67], S.pack [68..70], S.pack [71..73]] print x print $ B.toChunks x > program_chunks "ABCDEFGHI" ["ABC","DEF","GHI"] 39

ByteString: operacje na plikach przykładowy program z19.hs 40