--- 1. gyakorlat
-----
f(1) = A
f(2) = B
f(3) = C
------
f(1) = A
f(2) = A
f(3) = B
------
f(1) = A
f(1) = B
f(2) = C
------
1
2
1 + 2
(1 + 2) * 100 = 300
-------------
Melyik NEM függvény és miért?
f(x) = 1
f(z) = 2
g(X) = true
g(Y) = false
g(X) = false
h(1) = "hello"
h(3) = "world"
h(2) = "Haskell"
--- 2. gyakorlat
-----
-- masodik.hs
-- Windows parancsori értelmezők
-- powershell
-- cmd
-- Fájlok listázása: ls VAGY dir
-- ghci spéci parancsok
-- :l masodik.hs <- betöltés (load)
-- :r <- újratöltés (reload)
s = "Haskell is cool"
-- https://people.inf.elte.hu/poor_a/
inc n = n + 1
even' m = m `mod` 2 == 0
even'' m = mod m 2 == 0
-- Összehasonlító operátorok (függvények):
-- 2 == 2 egyenlő
-- 2 /= 3 nem egyenlő
-- 2 > 1 nagyobb
-- 2 >= 2 nagyobb vagy egyenlő
-- logikai operátorok (függvények):
-- True && True logikai ÉS
-- True || False logikai VAGY
-- Logikai ÉS művelet
-- True ÉS True -> True
-- True ÉS False -> False
-- False ÉS True -> False
-- False ÉS False -> False
-- Mintaillesztés:
and' True True = True
and' True False = False
and' False True = False
and' False False = False
and'' True True = True
and'' _ _ = False
--- 3. gyakorlat
-----
xor True True = False
xor True False = True
xor False True = True
xor False False = False
xor''''' False a = a
xor''''' True a = not a
xor' a b = a /= b
{-
xor'' True False = True -- parciális függvény
xor'' False True = True
-}
xor'' True False = True -- totális függvény
xor'' False True = True
xor'' a b = False
{-
-- Nem jó, mert minden paraméternek különböző nevet kell adni
xor''' True False = True
xor''' False True = True
xor''' a a = False
-}
xor'''' True False = True -- totális függvény
xor'''' False True = True
xor'''' _ _ = False -- catch all minta: _
{-
xor'''' _ _ = False
xor'''' True False = True -- totális függvény
xor'''' False True = True
-}
------
-- Karakter minták
isA 'a' = True
isA 'A' = True
isA _ = False
-----------
fugven 42 12
a fugven z -> mod a z \= 0 -- rossz
fugven a z = mod a z /= 0 -- helyes
a `fugven` z =
--- 4. gyakorlat
-----
fun 'a' = "is"
fun 'x' = "interesting"
fun 'y' = "functional"
fun _ = "Haskell"
-----
Kérdések:
"Haskell" "is" "functional"
Parciális vagy totális? Miért?
-----
-- downloads.haskell.org
nextDay a
| a < 0 = error "nextDay: input can't be negative"
| a > 6 = error "nextDay: input can't be greater than 6"
| a == 6 = 0
| otherwise = a + 1 -- otherwise nem kötelező, helyette szerepelhetne a < 6 is (mert már csak az maradt ki)
-- ez is ugyanolyan jó:
nextDay a
| a == 6 = 0
| 0 <= a && a < 6 = a + 1
| a < 0 = error "nextDay: input can't be negative"
| a > 6 = error "nextDay: input can't be greater than 6"
--- Rekurzió
-- Nem jó:
-- fact :: Integer -> Integer
-- fact n = n * fact (n-1) -- Rekurzív eset
-- Végtelen rekurzió:
-- Hiányzik a nem rekurzív alapeset
-- fact 2 -> 2 * fact 1 -> 2 * 1 * fact 0 -> 2 * 1 * 0 * fact (-1) ...
fact :: Integer -> Integer
fact 0 = 1 -- Alapeset (nem rekurzív függvényág)
fact n = n * fact (n-1) -- Rekurzív eset
--- 5. gyakorlat
-----
min' x y
| x <= y = x
| x > y = y
------
min'' x y
| x <= y = x -- ha elfogytak az őrfeltételek (mindegyik False volt), akkor megyünk a következő függvényágra
min'' x y -- azaz ide
| x > y = y
--- 6. gyakorlat
-----
descending :: Int -> [Int]
descending n = list
where -- segédváltozók és segédfüggvények
list = [n, n-1 .. (-n)]
data Something = SomeInt Int | SomeString String -- új saját adatszerkezet
--- 7. gyakorlat
-----
ghci> import Data.Char
ghci>
ghci>
ghci> [ c | c <- "Hello World", isUpper c]
"HW"
ghci> [ toLower c | c <- "Hello World", isUpper c]
"hw"
ghci> [ toLower c | c <- "Hello World", isUpper c, c elem ['a'..'g']]
""
ghci> [ toLower c | c <- "Hello World", isUpper c, c elem ['A'..'G']]
""
ghci> [ toLower c | c <- "Hello World", isUpper c, c elem ['A'..'H']]
"h"
--- 8. gyakorlat
-----
x^2 + 4x + 6 // x = 42
42^2 + 4*42 + 6
head :: [a] -> a // a = Int
head :: [Int] -> Int
zip :: [a] -> [b] -> [(a,b)] // a = Int, b = String
zip :: [Int] -> [String] -> [(Int, String)]
Ugyanazt jelenti a kettő minta listákon:
myMinimum [x] = x
myMinimum (x : []) = x
--- 9. gyakorlat
-----
infixr 3 +:+
(+:+) :: [a] -> [a] -> [a]
[] +:+ bs = bs
(a:as) +:+ bs = a : (as +:+ bs)
myConcat as bs = as +:+ bs
second (x, y) = y
--- 10. gyakorlat
-----
data Point = Coordinates Int Int
deriving (Eq, Ord)
-- Coordinates :: Int -> Int -> Point
-- ghci-ben
-- :t Coordinates
-- Coordinates :: Int -> Int -> Point
--
-- :i Eq
data TrafficLight = Red | Yellow | Green
deriving Show
-- data Int = ... | -3 | -2 | -1 | 0 | 1 | 2 | 3 ...
showPoint :: Point -> String
showPoint (Coordinates x y) = "(" ++ show x ++ ", " ++ show y ++ ")"
instance Show Point where
-- show :: Point -> String
show (Coordinates x y) = "(" ++ show x ++ ", " ++ show y ++ ")"
data MaybeInt = NothingInt | JustInt Int
deriving (Eq, Show)
showMaybeInt :: MaybeInt -> String
showMaybeInt NothingInt = "Itt nincs semmi"
showMaybeInt (JustInt n) = "Itt van egy szam: " ++ show n
data MaybeDouble = NothingDouble | JustDouble Double
deriving (Eq, Show)
data MaybeString = NothingString | JustString String
deriving (Eq, Show)
-- data Maybe a = Nothing | Just a
-- ^ típusparaméter
--
-------------
ghci> import Data.Maybe
ghci>
ghci>
ghci> listToMaybe [1,2,3]
Just 1
ghci> listToMaybe []
Nothing
ghci> listToMaybe "Haskell"
Just 'H'
ghci> :t listToMaybe "Haskell"
listToMaybe "Haskell" :: Maybe Char
ghci> :t listToMaybe ""
listToMaybe "" :: Maybe Char
ghci> listToMaybe ""
Nothing
ghci> listToMaybe [True, False]
Just True
ghci> :t listToMaybe [True, False]
listToMaybe [True, False] :: Maybe Bool
-------------
--- 11. gyakorlat
-----
map f [x1, x2, x3 ... xn] ==
[f x1, f x2, f x3 ... f xn]
ghci> map (+1) [1,2,3]
[2,3,4]
ghci> import Data.Char
ghci> map toUpper "haskell"
"HASKELL"
ghci> :t map
map :: (a -> b) -> [a] -> [b]
ghci> isUpper 'H'
True
ghci> isUpper 'h'
False
ghci> filter isUpper "Hello World"
"HW"
ghci> :t map
map :: (a -> b) -> [a] -> [b]
ghci> map length ["haskell", "is", "cool"]
[7,2,4]
ghci> map (filter isUpper) ["Haskell", "Is", "cOOl"]
["H","I","OO"]
ghci> filterUpper s = filter isUpper s
ghci> filterUpper "Haskell"
"H"
ghci> map filterUpper ["Haskell", "Is", "cOOl"]
["H","I","OO"]
ghci> :t filter
filter :: (a -> Bool) -> [a] -> [a]
ghci> filterChar c = isUpper c && c `elem` ['a'..'k']
ghci> filterChar 'a'
False
ghci> filterChar 'x'
False
ghci> filterChar 'A'
False
ghci> filterChar c = isUpper c && c `elem` ['A'..'K']
ghci> filterChar 'A'
True
ghci> filterChar 'K'
True
ghci> filterChar 'P'
False
ghci> filterChar c = isUpper c || c == ' '
ghci> filterChar 'P'
True
ghci> filterChar c = c `elem` ['A'..'K'] || c == ' '
ghci> filterChar 'P'
False
ghci> filterChar 'A'
True
ghci> filterChar ' '
True
ghci> filterChar 'a'
False
ghci> filter filterChar "Haskell"
"H"
ghci> filter filterChar "HaskeLL"
"H"
ghci> filter filterChar "HaskeLL is Functional"
"H F"
ghci> filter isUpper "Haskell"
"H"
ghci> filter isUpper "HaskeLL"
"HLL"
ghci> filter isLower (filter isUpper "HaskeLL")
""
ghci> filter (\n -> n > 2 && n < 5) [1,9,0,20,42,4,3,4,5]
[4,3,4]
ghci> (\n -> n > 2 && n < 5) 2
False
ghci> (\n -> n > 2 && n < 5) 3
True
ghci> (\n -> n > 2 && n < 5) 4
True
ghci> :t (\n -> n > 2 && n < 5)
(\n -> n > 2 && n < 5) :: (Ord a, Num a) => a -> Bool
ghci> between2and5 = (\n -> n > 2 && n < 5)
ghci> between2and5 3
True
ghci> between2and5 4
True
ghci> between2and5 5
False
-- Identitás függvény:
-- (\x -> x) -- Haskell
-- λx.x -- Lambda kalkulus
--
data Adat = Szemely String Int
deriving Show
data Person = NewHuman {
nev :: String,
szuletesiEv :: Int,
varos :: String
} deriving Show
--- 12. gyakorlat
-----
Függvénykompozíció is egy (magasabb rendű) függvény Haskellben:
(.) :: (b -> c) -> (a -> b) -> a -> c
Típus levezetése:
f :: b -> c
g :: a -> b
f . g :: a -> c
eltűnik a köztes 'b' típusú érték
reverse (dropSpaces (reverse (dropSpaces " Hello Haskell ")))
(reverse . dropSpaces . reverse . dropSpaces) " Hello Haskell "
Részeredmény felbontása függvényen belül kisebb komponensekre:
myGroup list = ...
where
(first, rest) = span (...) list
--- 13. gyakorlat
-----
data Brand = Ford | Suzuki | Volkswagen
deriving (Show, Eq, Ord, Enum)
data Car = Automobile Brand Int String
deriving (Show)
myCar :: Car
myCar = Automobile Volkswagen 5 "FKJ-245"
neighborsCar :: Car
neighborsCar = Automobile Suzuki 5 "ABC-123"
isVolkswagen :: Car -> Bool
isVolkswagen (Automobile brand doors license) = brand == Volkswagen
{-
isVolkswagen :: Car -> Bool
isVolkswagen (Automobile Volkswagen doors license) = True
isVolkswagen _ = False
-}
-------------
ghci> :{
ghci| isDivisible :: Int -> Int -> Bool
ghci| isDivisible a b = a `mod` b == 0
ghci| :}
ghci> isDivisible 10 2
True
ghci> isDivisible 10 3
False
ghci> :t isDivisible
isDivisible :: Int -> Int -> Bool
ghci> :t isDivisible 10
isDivisible 10 :: Int -> Bool
ghci> :t filter
filter :: (a -> Bool) -> [a] -> [a]
ghci> filter (isDivisible 10) [2,3,4,1,10,200,300,5]
[2,1,10,5]
ghci> words " Hello Haskell"
["Hello","Haskell"]
-------------
data TreeType = Birch | Oak | Beech | Maple deriving (Eq, Show)
data Tree = Alive TreeType Age
| Dead TreeType Age
deriving (Eq, Show)
type Age = Integer
updateTreeAge :: Tree -> Tree
updateTreeAge (Alive typ age) = Alive typ (age + 1)
updateTreeAge (Dead typ age) = Dead typ age
{-
updateTreeAge :: Tree -> Tree
updateTreeAge (Alive typ age) = Alive typ (age + 1)
updateTreeAge tree = tree
-}
updateTreeAges :: [Tree] -> [Tree]
updateTreeAges trees = map updateTreeAge trees