Wykład przeznaczony jest dla studentów I roku I stopnia Informatyki Algorytmicznej.
Odbywa się we wtorki w godz. -
w sali 0.32 w budynku C-13.
Na stronie tej znajdziesz informacje o zasadach zaliczenia, literaturze, realizowanym materiale oraz listę zadań.
Literatura
Podstawowa
Miran Lipovaca, Learn You a Haskell for Great Good! A Beginner's Guide, No Starch Press,
Will Kurt, Get Programming with Haskell, Manning,
Bryan O’Sullivan, John Goerzen, and Don Stewart, Real World Haskell, O’Reilly,
Benjamin C. Pierce, Basic Category Theory for Computer Scientists, The MIT Press,
Pomocnicza:
S. Tompson, Haskell. The craft for functional Programming, Addison Wesley,
B. Milewski, Category Theory for Programmers, Creative Licence,
Na laboratoriach będziecie oceniani za aktywność. Rozwiązania zadań będą oceniane w skali 0-2 pkt (w zależości od stopnia trudności, ustalonego przez prowadzącego). Do zdobycia będzie 20 pkt.
Pod koniec maja będą ogłoszone tematy kilku projektów do wyboru. Będziecie mogli je ralizować samodzielnie lub w dwuosobowych grupach. Za realizację projektu będzie można dostać do 10 pkt.
Ocena dostateczna będzie od 10 punktów.
$
\def\RR{\mathbb{R}}
\def\QQ{\mathbb{Q}}
\def\ZZ{\mathbb{Z}}
\def\CC{\mathbb{C}}
\def\NN{\mathbb{N}}
\def\IFF{\leftrightarrow}
\newcommand{\span}[1]{\mathrm{span}(#1)}
\newcommand{\IS}[2]{\langle\,#1,#2\rangle}
\newcommand{\sgn}[1]{\mathrm{sgn}(#1)}
$
Zagadnienia omówione na wykładzie
W1 (04.03.2025): GHCI i funkcje
Podstawowe polecenie ghci:
:q = wyjście
:t = typ
:i = info
:l = załadowanie modułu
Część kodów, które pojawiły się na tablicy.
module W1 where
-- funkcja jednej zmiennej
f x = 1 + x*(x+1)
g::Num a => a -> a -> a
g x y = 1 + x*y
-- Silnia : IF ... ELSE ...
fact1 :: Integer -> Integer
fact1 n = if n==0 then 1
else n * fact1 (n-1)
-- partition
{- komentuje, bo jest w Data.List
partition :: (a->Bool) -> [a] ->([a],[a])
partition _ [] = ([],[])
partition p (x:xs) = if p x then (x:l,r)
else (l,x:r)
where (l,r) = partition p xs
-}
-- liczby pierwsze sieve (p:xs) = p : sieve (filter (\n -> mod n p /= 0) xs) primes = sieve [2..]
better_sieve (p:xs) = p: sieve (filter(\n -> n<p*p ||(mod n p /= 0)) xs)
addGF xs ys = zipWith (+) xs ys
Konstrukcja "type"
module Fizyka(Point,Vector,Time,
move, translate, moveInGF) where
type Point = (Double,Double)
type Vector = (Double,Double)
type Time = Double
constG = 9.80655
-- lokalna funkcje
generalMove :: Point -> Vector -> Time -> Double -> Point
generalMove (x,y) (vx,vy) t acc = (x+vx*t, y + vy*t + acc*t*t/2)
-- upublicznione
move :: Point -> Vector -> Time -> Point
move p v t = generalMove p v t 0
translate :: Point -> Vector -> Point
translate p v = generalMove p v 1 0
moveInGF :: Point -> Vector -> Time -> Point
moveInGF p v t = generalMove p v t (-constG)
Konstrukcja "data" - wstęp
module W04b where
{-- Typy numerowane --}
data DOW = Po|Wt|Sr|Cz|Pi|So|Ni deriving (Eq,Ord,Enum,Bounded)
instance Show DOW where
show Po = "Poniedziałek"
show Wt = "Wtorek"
show Sr = "Środa"
show Cz = "Czwartek"
show Pi = "Piatek"
show So = "Sobota"
show Ni = "Niedziela"
dniPracujace = [Po .. Pi] -- efekt Enum
Proponuję rzucić okiem na następującą stronę:
The Evolution of a Haskell Programmer, na której Fritz Ruehr'er wygłupia się z różnymi sposobami zdefiniowania funkcji silnia.
W5 (01.04.2025): Typy, wstęp do funktorów
Zastosowania foldów i strumienie
module W5b where
-- prototyp
data Osoba' = Osoba' String String String Int Int Int
imie' :: Osoba' -> String
imie' (Osoba' _ x _ _ _ _) = x
-- itd
{-- RECORD SYNTAX --}
data Osoba = Osoba
{
idO :: String
,imie :: String
,nazwisko :: String
,rokUr :: Int
,miesiacUr :: Int
,dzienUr :: Int
} deriving (Show,Eq)
data Date = Date{rok::Int,miesiac::Int,dzien::Int}
deriving(Eq)
instance Show Date where
show (Date r m d) =
(show r) ++"."++(show m)++"."++(show d)
data Person = Person
{
_idO :: String
,_imie :: String
,_nazwisko :: String
, dataUr :: Date
} deriving (Show,Eq)
ccc = Person "001" "Anna" "Balicka" (Date 2005 5 12)
zmienDate :: Person -> Date -> Person
zmienDate osoba nowaData =
osoba{dataUr = nowaData}
zmienRokUr :: Person ->Int -> Person
zmienRokUr osoba rokUr =
let urodziny = dataUr osoba
urodziny' = urodziny{rok = rokUr} in
osoba{dataUr = urodziny'}
-- to samo - inny zapis
zmienRokUr' osoba rokUr =
osoba{dataUr = (dataUr osoba){rok = rokUr}}
--- Pozniej: lenses
{-- TYPY PARAMETRYZOWALNE --}
-- MODEL KATEGORYJNY: PP (X) = X x X
data Para a = Para (a,a) deriving (Show,Eq)
-- MODEL :: jesli f:X->Y to (fmap f):(X x X) -> (Y x Y)
instance Functor Para where
fmap f (Para (x,y)) = Para (f x, f y)
--pmap :: (a->b) -> Para a -> Para b
--pmap f (Para (x,y)) = Para (f x, f y)
f x = 3.5 * x*(1-x)
-- uzycie: fmap f Para(0.25,0.75)
{-- FUNKTOR MAYBE --}
-- data Maybe a = Nothing | Just a
-- MODEL: MB(X) = ({0} x {*}) u ({1} x X)
-- fmap f Nothing = Nothing
-- fmap f (Just x) = Just (f x)
safeHead [] = Nothing
safeHead (x:_) = Just x
safeSqrt x
| x>=0 = Just (sqrt x)
| otherwise = Nothing
safeLog x
| x>0 = Just (log x)
| otherwise = Nothing
safeDiv x 0 = Nothing
safeDiv x y = Just (x/y)
-- zaczynamy partyzantkę;
-- pozniej zrobimy to lepiej
-- sqrt(log x)
composeMB :: (a-> Maybe b) -> (b -> Maybe c) -> (a -> Maybe c)
composeMB f g x =
case f x of
Nothing -> Nothing
Just y -> g y
expr1 = composeMB safeLog safeSqrt
-- (sqrt x)/log(x +1)
composeMB2 :: (a->b->Maybe c) -> Maybe a -> Maybe b -> Maybe c
composeMB2 _ Nothing _ = Nothing
composeMB2 _ _ Nothing = Nothing
composeMB2 op (Just x) (Just y) = op x y
expr2 x = let sn = safeSqrt x
sd = safeLog (x^2-4) in
composeMB2 safeDiv sn sd
Oto skompresowany plik
W5_BD.zip, z plikami którymi bawiliśmy się na wykładzie.