Pobieranie prezentacji. Proszę czekać

Pobieranie prezentacji. Proszę czekać

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.

Podobne prezentacje


Prezentacja na temat: "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."— Zapis prezentacji:

1 Haskell

2 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 miejsc". W wyniku, o ile nastąpiło dopasowanie otrzymuje się listę wyrażeń, które dopasowały się do wolnych miejsc wzorca. W językach funkcyjnych wykorzystuje się system wzorców symbolicznych.

3 Dopasowanie do wzorca Przykład: Aplikacja, która wypisze „Trafiłeś szczęśliwą liczbę” w przypadku napotkania siódemki, oraz „Liczba nie jest szczęśliwa” w przeciwnym wypadku. Plik szczesliwaLiczba.hs szczesliwaLiczba::(Integral a)=> a-> String szczesliwaLiczba 7 = "Trafiles szczesliwa liczbe." szczesliwaLiczba x = "Liczba nie jest szczesliwa. "

4 Dopasowanie do wzorca Ten sam przykład można zapisać w nieco inny sposób: szczesliwaLiczba n = case n of 7 -> "Trafiles szczesliwa liczbe." _ -> "Liczba nie jest szczeliwa" Lub szczesliwaLiczba n | n == 7 = " Trafiles szczesliwa liczbe. " | otherwise = " Liczba nie jest szczeliwa "

5 Dopasowanie do wzorca W kolejnym przykładzie sprawdzimy czy liczba mieści się w zakresie i wypiszemy ją jako string. Przykład: 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"

6 Silnia rekurencyjnie Przypomnienie czym jest silnia: Jest to iloczyn wszystkich liczb naturalnych nie większych niż n. 4! = 1 · 2 · 3 · 4 = 24. Przypomnienie czym jest rekurencja: Odwoływanie się funkcji do samej siebie.

7 Silnia rekurencyjnie Przykład: fac :: Int -> Int fac n | n = 0" | n == 0 = 1 | otherwise = n * fac (n - 1)

8 Silnia rekurencyjnie – drugi sposób Przykład: factorial :: (Integral a) => a -> a factorial 0 = 1 factorial n = n * factorial (n - 1)

9 Silnia rekurencyjnie – drugi sposób Wyjaśnienie działania dla n=3. W pierwszym kroku obliczamy 3 * silnia(2) Silnia(2) to: 2 * silnia(1) Silnia(1) to 1 * Silnia(0) Co w sumie daje: 3 * (2 * (1 * silnia 0)) Z czego otrzymujemy 3 * (2 * (1 * 1)) Z tego wynika, że kolejność jest bardzo istotna!

10 Krotki na przykładzie wektorów Dodanie do siebie dwóch wektorów. Komponenty x muszą być dodane oddzielnie, oraz ich elementy y oddzielnie. addVectors :: (Num a) => (a, a) -> (a, a) -> (a, a) addVectors a b = (fst a + fst b, snd a + snd b) lub addVectors :: (Num a) => (a, a) -> (a, a) -> (a, a) addVectors (x1, y1) (x2, y2) = (x1 + x2, y1 + y2)

11 Krotki na przykładzie wektorów A co, jeśli chcielibyśmy użyć trójek? _ oznacza cokolwiek first :: (a, b, c) -> a first (x, _, _) = x second :: (a, b, c) -> b second (_, y, _) = y third :: (a, b, c) -> c third (_, _, z) = z Przykład: ghci > let xs = [(1,3), (4,3), (2,4), (5,3), (5,6), (3,1)] ghci > [a+b | (a,b) <- xs] [4,7,6,8,11,4]

12 Inne przykłady - listy head ' :: [a] -> a head ' [] = error "Can't call head on an empty list, dummy!" head ' (x:_) = x [] – oznacza listę pustą ghci > head ' [4,5,6] 4 ghci > head ' "Hello" 'H'

13 Inne przykłady - listy 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

14 Przykład z BMI bmiTell :: (RealFloat a) => a -> String bmiTell bmi | bmi <= 18.5 = "You're underweight, you emo, you!" | bmi <= 25.0 = "You're supposedly normal. Pffft, I bet you're ugly!" | bmi <= 30.0 = "You're fat! Lose some weight, fatty!" | otherwise = "You're a whale, congratulations!„ bmiTell :: (RealFloat a) => a -> a -> String bmiTell weight height | weight / height ^ 2 <= 18.5 = "You're underweight, you emo, you!" | weight / height ^ 2 <= 25.0 = "You're supposedly normal. Pffft, I bet you're ugly!" | weight / height ^ 2 <= 30.0 = "You're fat! Lose some weight, fatty!" | otherwise = "You're a whale, congratulations!" Let’s see if I’m fat... ghci > bmiTell 85 1.90 "You're supposedly normal. Pffft, I bet you're ugly!"

15 Przykład z WHERE bmiTell :: (RealFloat a) => a -> a -> String bmiTell weight height | bmi <= 18.5 = "You're underweight, you emo, you!" | bmi <= 25.0 = "You're supposedly normal. Pffft, I bet you're ugly!" | bmi <= 30.0 = "You're fat! Lose some weight, fatty!" | otherwise = "You're a whale, congratulations!" where bmi = weight / height ^ 2 Lub bmiTell :: (RealFloat a) => a -> a -> String bmiTell weight height | bmi <= skinny = "You're underweight, you emo, you!" | bmi <= normal = "You're supposedly normal. Pffft, I bet you're ugly!" | bmi <= fat = "You're fat! Lose some weight, fatty!" | otherwise = "You're a whale, congratulations!" where bmi = weight / height ^ 2 skinny = 18.5 normal = 25.0 fat = 30.0

16 Przykład z LET 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

17 CASE case expression of pattern -> result pattern -> result...

18 CZĘŚĆ 2  REKURENCJA Żeby zrozumieć rekurencję, musisz zrozumieć rekurencję.

19 Silnia Ćwiczenie -> zaimplementować silnie, była już omawiana.

20 Mnożenie Z pewnością każdy programista, zarówno piszący w językach imperatywnych jak i funkcyjnych, aby pomnożyć dwie liczby a i b napisze po prostu a * b. Mnożenie można jednak zapisać w sposób rekurencyjny. Wykorzystamy do tego definicję podawaną dzieciom w szkole podstawowej. Aby pomnożyć liczbę a razy liczbę b, weź liczbę a i dodaj do siebie b razy. Na przykład 6*4 = 6+6+6+6. Podobnie jak w poprzednim przykładzie, zapiszmy dwa przykłady mnożenia. 6 * 4 = 6 + 6 + 6 + 6 6 * 3 = 6 + 6 + 6

21 Mnożenie – uogólnienie a * b = a + a * (b-1) Oraz przypadek bazowy a * 0 = 0

22 Implementacja Samodzielnie zaimplementuj pomnoz a 0 = 0 pomnoz a b = a + pomnoz a (b-1)

23 Maxiumum maksimum :: [Int] -> Int maksimum [x] = x maksimum (x:xs) | x > maks = x | otherwise = maks where maks = maksimum xs

24 Rekurencja ogonowa Rekurencja ogonowa, zwana też Tail call lub prawostronną jest rodzajem rekurencji, w której ostatnia operacja wykonywana przez funkcję to rekurencyjne wywołanie samej siebie lub zwrócenie końcowego wyniku. Taka funkcja może zostać łatwo zamieniona na iterację, zarówno ręcznie, jak i automatycznie, co redukuje wielkość stosu oraz zwiększa wydajność. Ta technika iteracyjnego wykonywania obliczeń jest powszechna w programowaniu funkcyjnym promującym używanie rekurencji, która w przeciwnym wypadku zajęłaby cały dostępny stos.

25 Rekurencja ogonowa maksimum' :: [Int] -> Int maksimum' (x:xs) = maks xs x where maks [] m = m maks (x:xs) m | x > m = maks xs x | otherwise = maks xs m


Pobierz ppt "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."

Podobne prezentacje


Reklamy Google