Types and Typeclasses Syntax in Functions

Slides:



Advertisements
Podobne prezentacje
Tablice 1. Deklaracja tablicy
Advertisements

Funkcje w PHP ABK.
C++ wykład 2 ( ) Klasy i obiekty.
Język C/C++ Funkcje.
Programowanie obiektowe
Programowanie obiektowe
Wzorce.
Język ANSI C Funkcje Wykład: Programowanie komputerów
Prowadzący: mgr inż. Elżbieta Majka
Języki programowania C++
PROGRAMOWANIE STRUKTURALNE
formatowanie kodu źródłowego
Materiały do zajęć z przedmiotu: Narzędzia i języki programowania Programowanie w języku PASCAL Część 7: Procedury i funkcje © Jan Kaczmarek.
Materiały do zajęć z przedmiotu: Narzędzia i języki programowania Programowanie w języku PASCAL Część 8: Wykorzystanie procedur i funkcji © Jan Kaczmarek.
Materiały do zajęć z przedmiotu: Narzędzia i języki programowania Programowanie w języku PASCAL Część 5: Typy porządkowe, wyliczeniowe i okrojone. Definiowanie.
Instrukcje Instrukcja : definicja obliczenia i określenie sposobu wykonania tego obliczenia. Program : ciąg instrukcji wykonywanych kolejno od pierwszej.
Programowanie imperatywne i język C Copyright, 2004 © Jerzy R. Nawrocki Wprowadzenie.
Programowanie imperatywne i język C
Programowanie imperatywne i język C Copyright, 2004 © Jerzy R. Nawrocki Wprowadzenie.
Kurs Pascala – spis treści
Struktury.
Tablice.
1 Dygresja: cztery płyty główne…. 2 Dygresja: osobliwości C /* cos o nieistniejacym typie Boolean */ /* oraz o operatorze przecinkowym */ #include int.
Ogólne jednostki programowe 1
Tablice jednowymiarowe 1
Typy danych – podstawy 1 W Adzie wszystkie dane muszą być określonego typu. Definicja Typ danych (data type) jest to zbiór wartości i operacji, które można.
Typy prywatne 1 Typy prywatne W Adzie typy prywatne (private types) służą do bezpiecznego udostępniania danych zdefiniowanych w pakiecie, z którego korzysta.
Wykład 2 struktura programu elementy języka typy zmienne
Instrukcja skoku GO TO etykieta Np. GO TO 100 ….. 100WRITE (*,*) Przeskok do instrukcji 100 Uwaga! NIE WOLNO skakać do wnętrzna złożonych instrukcji warunkowych.
Wprowadzenie do programowania w języku Turbo Pascal
Schemat Hornera Mgr inż. Michał Szucki.
AWK Zastosowania Informatyki Wykład 1 Copyright, 2003 © Adam Czajka.
Podstawy C# Grupa .NET PO.
Podstawy programowania
Podstawy programowania
Programowanie strukturalne i obiektowe
TABLICE C++.
JAVA c.d.. Instrukcji wyboru SWITCH używamy, jeśli chcemy w zależności od wartości pewnego wyrażenia wykonać jeden z kilku fragmentów kodu. Jest to w.
Andrzej Repak Nr albumu
XML – eXtensible Markup Language
Zbiory i rekordy mgr inż. Agata Pacek. Deklaracja typu zbiorowego (określa ilość elementów w zbiorze) type biegi=set of 0..6; Definiowanie zmiennej typu.
Podstawy informatyki 2013/2014
Przekazywanie parametrów do funkcji oraz zmienne globalne i lokalne
Visual Basic for Applications Poziom podstawowy Zajęcia 2
Wykład 10 typ zbiorowy rekurencja.
Kurs języka C++ – wykład 9 ( )
PL/SQL – dalsza wędrówka
Programowanie strukturalne i obiektowe C++
Zmienne i typy danych w C#
Krakowski Piotr, Woliński Radosław, Kowalski Piotr, Machowski Michał.
Haskell. Dopasowanie do wzorca Jest to operacja, gdzie pewnie wyrażenie sprawdza się ze wzorcem, w którym może znajdować się jedno lub więcej "wolnych.
Typy liczbowe, zmienne, operatory Zajęcia 4. Zmienne Zmienna – to w programowaniu element programu, który może mieć przypisaną pewną wartość (wartość.
Programowanie imperatywne i język C Copyright, 2007 © Jerzy R. Nawrocki Wstęp do.
Pętle – instrukcje powtórzeń
PHP jest językiem skryptowym służącym do rozszerzania możliwości stron internetowych. Jego składnia jest bardzo podobna do popularnych języków programowania.
Wstęp do programowania Wykład 2 Dane, instrukcje, program.
Visual Basic przygotował Michał Miłek Visual Basic – język programowania wysokiego poziomu i narzędzie programistyczne firmy Microsoft. Składnia jest oparta.
P ASCAL Definicje, deklaracje, podstawowe instrukcje 1.
Rekurencja - Haskell Bartosz Pawlak Sebastian Żółtowski Adam Stegenda Krystian Sobótka Tomasz Gołębiewski.
Typy wyliczeniowe, kolekcje
Rozdział 5 REKURENCJA.
Typy i typy klas.
Funkcje wyższego rzędu
Delegaty Delegat to obiekt „wiedzący”, jak wywołać metodę.
Programowanie Obiektowe – Wykład 2
Funktory, funktory aplikatywne, MONoidy
Functors, Applicative Functors and Monoids
Haskell Składnia funkcji.
Język C++ Typy Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi i Pawła Jerzego.
Zapis prezentacji:

Types and Typeclasses Syntax in Functions (Gaik Dawid, Marciniak Michał)

* Funkcja bez definicji typu * Funkcja z jawną definicją typu Typy i Klasy typów Typy w jęzku Haskell Rozpoznawanie typu Typy funkcji * Funkcja bez definicji typu * Funkcja z jawną definicją typu Typy całkowite i zmienne Klasy typów

Typy w języku haskell Wszystkie typy i wyrażenia znane są w języku Haskell już podczas kompilacji (mają zdefiniowany typ), co daje nam bardzo dużą zaletę - zwiększa bezpieczeństwo kodu, zabezpieczając nas przed ewentualnymi problemami w działaniu aplikacji. Nazwa wszystkich typów w języku Haskell zaczynają się od dużej litery np. Char, Bool. Aby sprawdzić dowolny typ wyrażenia, można użyć polecenia ,,:t " :

Rozpoznawanie typów Język Haskell pozwala na samoczynne wywnioskowanie typów zmiennych i argumentów funkcji, dlatego ich jawne podawanie jest zbędne. Jest to jedna z cech Haskella, ktora wyróżnia go na tle innych języków, pozwalając na większą swobodę w programowaniu.

Funkcja bez definicji typu Wbudowana rozpoznawalność typów przez Haskella pozwala nam większą swobodę podczas programowania i nie wymaga od nas definiowania jawnego typu plików przy tworzeniu prostych funkcji. Funkcje bez definicji typu dobrze widać na przykładzie prostej funkcji, writeit x=x++"!" która ma za zadanie dopisanie znaku "!" do podanego wyrazu. Funkcja będzie posiadała typ [Char]->[Char] co oznacza mapowanie typu znakowego na typ znakowy. Użycie "[]" świadczy o tym, że mamy do czynienia z listą znaków - w tym wypadku listą znaków typu Char. Wynik naszej funkcji po sprawdzeniu typu Wynik funkcji Sprawdzenie typu

Funkcja Z JAWNĄ DEFINICJĄ TYPU Rozważmy teraz funkcje, której zadanie będzie takie samo jak w Funkcji bez definicji typu, czyli dopisanie znako "!" na koniec podanego wyrazu. Typ [Char] jes równoważny ze String`iem, który jest po prostu pojedyńczą listą znaków typu Char. writeit :: String -> String writeit x=x++ "!„ Definiując typ dla parametrów funkcji, używamy symbol "->". Typ zwracanej wartości znajduje się na końcu definiowanych typów. Wynik funkcji Sprawdzenie typu

Integer - typ całkowity (Nie posiada ograniczeń do 32 bitów), TYPY CAŁKOWITE Typy całkowite : Int - ograniczony typ całkowity (Liczba całkowita zaisywana na 32 bitach), Integer - typ całkowity (Nie posiada ograniczeń do 32 bitów), Float - typ z pojedyńczą precyzją Double - typ z podwójną precyzją, Inne typy: "Bool", "Char"

TYPY Zmienne W języku Haskell oprócz typów całkowitych, występują także typy zmienne, których konstrukcja nie narzuca z góry określonego typu dla parametru. Przykładem może być funkcja fst: która pobiera dwuelementową krotkę i zwraca element będący tym samym typem co pierwszy element tej krotki (Elementy a i b nie muszą być tego samego typu)

TYPY Zmienne Operatory ==,+,*,- i / oraz wiele innych to funkcje w Haskellu. Funkcja zawierająca jedynie znaki specjalne to tak zwana funkcja infiksowa. Aby sprawdzić na jakich typach pracuje, musimy przekazać ją do innej funkcji lub uczynić tę funkcję prefiksową (Nazwę funkcji zawrzeć w nawiasach). Część wyrażenia, występująca przed symbolem => nazywana jest klasą ograniczeń, Funkcje, które przyjmują typ zmienny nazywamy funkcjami polimorficznymi.

Klasy typów Klasy typów - Typeclasses to mechnizmy określające zachowanie poszczególnych typów związanych z daną klasą. Typ, będący Typeclass ma zaimplementowane pewne zachowania, które opisuje type class. Symbol => jest ograniczeniem klasy, nazywany jest class constraint Eq jeden z podstawowych typów klass w Haskellu. Używany w porównaniach

Klasy typów - eQ Typeclass Eq - udostępnia interfejs do testowania równości. Klasa dla typów używanych w porównaniach (==, /=). Standard języka Haskell wymaga aby wszystkie typy i funkcje (z wyjątkiem IO) należały do klasy Eq.

Klasy typów - ORD Typeclass Ord - dla typów używanych w porządkowaniu wartości (<, >, <=, >=). Funkcje porównujące pobierają dwa argumenty tego samego typu, które należą do klasy Ord i zwracają obiekt klasy Ordering tzn - EQ, GT lub LT (Greater than, Lesser than, Equal) Aby typ należał do klasy Ord musi należeć do klasy Eq

Klasy typów – SHOW i Read Typeclass Show - dla typów, które mogą być prezentowane jako String. Najcześciej w klasie typu Show wykorzystywana jest funkcja show, która pobiera wartość i wyświetla ją jako tekst. Typeclass Read - funkcja odwrotna do Typeclass show. Pobiera tekst i zwraca typ należący do Read.

Klasy typów - ENUM Typeclass Enum - klasa obiektód do którego należą typy, które mogą być wliczalne. W tym typie mamy dostęp do funkcji pred (poprzednik) i succ (następnik). Do tej klasy należą typy ; (), Bool, Char, Ordering, Int, Integer, Float, Double

Klasy typów - BOUNDED Typeclass Bounded - typy mające wartości graniczne należą do tej klasy. Funkcja minBound zwraca minimalną wartość danego typu, a maxBound maksymalną wartość.

Pozostałe typy klas Typeclass Num - dla wszystkich typów numerycznych, Typeclass Integral - dla typów liczb całkowitych, Typeclass Floating - dla typów liczb zmiennoprzecinkowych,

Porównywanie wzorca (Pattern matching) Składanie w funkcji Porównywanie wzorca (Pattern matching) Strażnicy (instrukcje warunkowe) Instrukcja Where Instrukcja Let Wyrażenie Case

Porównywanie wzorca (Pattern matching) Haskel pozwala nam używać w składni funkcji, konkretnego wzorca, który jest porównywany z parametrami wejściowymi fukcji (matching) następnie na podstawie tego wzorca wykonywane są operacje. Składnia takiej funkcji pozwala na implementację różnych zachowań funkcji w zależności od wykorzystywanego wzorca.

Porównywanie wzorca (Pattern matching) Oto przykład użycia wzorca: sayMe :: (Integral a) => a -> String sayMe 1 = "One!" sayMe 2 = "Two!" sayMe 3 = "Three!" sayMe 4 = "Four!" sayMe 5 = "Five!" sayMe x = "Not between 1 and 5"

Porównywanie wzorca (Pattern matching) sayMe :: (Integral a) => a -> String * Na początku deklarujemy nazwę, * Następnie typ który funkcja ma przyjąć (Integral – typ liczb całkowitych) Na koniec zwracany typ, w tym przypadku będzie to String sayMe 1 = "One!" sayMe 2 = "Two!" Powyższe wzorce oznaczają, że dla konkretnego parametru wejściowego funkcja ma zwrócić przypisany parametr wyjściowy.

Porównywanie wzorca (Pattern matching) sayMe x = "Not between 1 and 5" Powyższe wyrażenie oznacza: dla dowolnego parametru wypisz "Not between 1 and 5„ a więc dla 1,2,3,4,5 również! Dla tego wzorzec ten został zaimplementowany dopiero na końcu składni, ma służyć jako zabezpieczenie na wypadek pozostałych parametrów nie uwzględnionych we wcześniejszych wzorcach (takie else ze znanych nam instrukcji warunkowych)

Porównywanie wzorca (Pattern matching) Należy również wspomnieć, iż weryfikacja wzorca następuje od góry do dołu a więc gdybyśmy poprzednią funkcję napisali w ten sposób: sayMe :: (Integral a) => a -> String sayMe x = "Not between 1 and 5" sayMe 1 = "One!" sayMe 2 = "Two!" …. Funkcja dla każdego parametru zwracałaby "Not between 1 and 5"

Porównywanie wzorca (Pattern matching) Rekurencja przy użyciu wzorca: silnia:: (Integral a) => a -> a silnia 0 = 1 silnia n = n * silnia(n - 1)

Porównywanie wzorca (Pattern matching) Przykład błędu gdy nie zakończymy składnii, wzorcem dla wszelkich pozostałych parametrów: charName :: Char -> String charName ’a’ = "Albert" charName ’b’ = "Broseph" ghci > charName ’h’ "*** Exception: tut.hs:(53,0)-(55,21): Non-exhaustive patterns in function charName Exception widoczny przy wywołaniu funkcji dla nie zabezpieczonego parametru ‚h’

Porównywanie wzorca (Pattern matching) Za pomocą wzorca napiszemy funkcję pobierające kolejne elementy: first :: (a, b, c) -> a first (x, _, _) = x second :: (a, b, c) -> b second (_, y, _) = y third :: (a, b, c) -> c third (_, _, z) = z

Porównywanie wzorca (Pattern matching) Implementacja znanej już nam funkcji head, która wypisuje pierwszy element listy: head ’ :: [a] -> a head ’ [] = error „podałeś pustą listę” head ’ (x:_) = x

Porównywanie wzorca (Pattern matching) tell :: (Show a) => [a] -> String tell [] = "The list is empty" tell (x:[]) = "The list has one element: " ++ show x tell (x:y:[]) = "The list has two elements: " ++ show x ++ " and " ++ show y tell (x:y:_) = "This list is long. The first two elements are: " ++ show x ++ " and " ++ show y

Porównywanie wzorca (Pattern matching) Suma elementów listy: capital :: String -> String capital "" = "Empty string , whoops!" capital all@(x:xs) = "The first letter of " ++ all ++ " is " ++ [x] ghci > capital "Dracula" "The first letter of Dracula is D"

Strażnicy (Guards) Strażnik jest w Haskell mechanizmem w sowim działaniu bardzo zbliżonym do warunku „if”. Wynikiem działania strażników jest wartość logiczna „True” lub „False”. Dodatkowo strażnicy bardzo dobrze współpracują z wcześniej opisanym mechanizmem porównywania wzorców.

Strażnicy (Guards) bmiTell :: (RealFloat a) => a -> String bmiTell bmi | bmi <= 18.5 = „jesteś zbyt chudy” | bmi <= 25.0 = „wszystko w normie" | bmi <= 30.0 = „pomyśl nad dietą" | otherwise = „powodzi się…” Deklarujemy wzorzec. Następnie deklarujemy instrukcje warunkową przy pomocy „|” oraz warunek a po znaku „=” deklarujemy parametr który ma zostać zwrócony. W celu zabezpieczenia funkcji dla pozostałych przypadków używamy „otherwise”

Strażnicy (Guards) bmiTell :: (RealFloat a) => a -> a -> String bmiTell weight height | weight / height ^ 2 <= 18.5 = „jesteś zbyt chudy” | weight / height ^ 2 <= 25.0 = „wszystko w normie" | weight / height ^ 2 <= 30.0 = „pomyśl nad dietą" | otherwise = „powodzi się…” Możemy tego również używać dla wielu parametrów wykonując operacje w deklaracji strażnika.

Strażnicy (Guards) max’ :: (Ord a) => a -> a -> a max’ a b | a > b = a | otherwise = b

Where Z poprzedniego przykładu można zauważyć, że cały czas powtarzany jest wzór na BMI a dokładniej„ weight / height ^ 2 „ W celu uniknięcia tego i używania raz zdefiniowanej wartości w całej składnii funkcji użyjemy where nazywane w także wiązaniem. Where na końcu funkcji łączy wyrażenie ze zmiennymi.(widoczne jest w całej funkcji).

Where bmiTell :: (RealFloat a) => a -> a -> String bmiTell weight height | bmi <= skinny = „jesteś zbyt chudy” | bmi <= normal = „wszystko w normie" | bmi <= fat = „pomyśl nad dietą" | otherwise = „powodzi się…” where bmi = weight / height ^ 2 skinny = 18.5 normal = 25.0 fat = 30.0 Warunek where umieszczamy zaraz po naszych strażnikach ( na końcu funkcji)

Let Wyrażenie Let jest w swoim działaniu bardzo podobne do wyrażenia Where i jest również nazywane wiązaniem. Z tą różnicą, że Let przypisuje wartość do podanych zmiennych lokalnie tzn. zmienna nie będzie widoczna w całej funkcji. Zasada działania Let < łączenia> in <wyrażenie> Zmienne zdefiniowane w części łączenia są dostępne w części wyrażenia. Let dokonuje łączenia wyrażenia ze zmienną na początku, a zmienna jest wykorzystywana w funkcji później.

LET ghci > [let square x = x * x in (square 5, square 3, square 2)] [(25,9,4)] ghci > (let a = 100; b = 200; c = 300 in a*b*c, let foo="Hey "; bar = "there!" in foo ++ bar) (6000000,"Hey there!") Przy deklaracji wielu zmiennych oddzielamy je średnikiem. Instrukcji let możemy używać zamiast if: ghci > 4 * ( if 10 > 5 then 10 else 0) + 2 ghci > 4 * ( let a = 9 in a + 1) + 2

LET calcBmis :: (RealFloat a) => [(a, a)] -> [a] calcBmis xs = [bmi | (w, h) <- xs, let bmi = w / h ^ 2] ghci > let zoot x y z = x * y + z ghci > zoot 3 9 2 29 ghci > let boot x y z = x * y + z in boot 3 4 2 14 ghci > boot <interactive >:1:0: Not in scope: ‘boot ’ Jeżeli pominiemy in, nasza zmienna związana z danym wyrażeniem będzie widoczna dla całej sesji:

Wyrażenie Case Jak w każdym języku programowania w tym również dostajemy wyrażenie case Zasada działania case expression of pattern -> result pattern -> result ... Wyrażenie jest porównywane ze wzorem, a gdy pasuje podawany jest wynik. W przypadku gdy żaden wzór nie pasuje, dostaniemy exception

Wyrażenie Case describeList :: [a] -> String describeList xs = "The list is " ++ case xs of [] -> "empty." [x] -> "a singleton list." xs -> "a longer list.„ describeList xs = "The list is " ++ what xs where what [] = "empty." what [x] = "a singleton list." what xs = "a longer list."