FP / Typové triedy a polymorfizmus

Typové triedy
a polymorfizmus

Funkcionálne programovanie

Skôr než začneme

data Pos = Pos Int Int

data Board = Board 
    Pos   -- size
    Int   -- number of mines
    [Pos] -- mines
    [Pos] -- opened tiles
    [Pos] -- marked tiles

Prístup k častiam štruktúry

boardSize :: Board -> Pos
boardSize (Board size _ _ _ _) = size

Zmena

markTile :: Board -> Pos -> Board
markTile (Board size num mines opened marked) pos =
    Board size num mines opened (pos:marked)

Record Syntax

data Pos = Pos { posRow :: Int , posCol :: Int }

data Board = Board 
    { boardSize :: Pos
    , boardNumMines :: Int
    , boardMines :: [Pos]
    , boardOpened :: [Pos]
    , boardMarked :: [Pos]
    }

Práca so štruktúrou

boardSize :: Board -> Pos
markTile :: Board -> Pos -> Board
markTile board pos =
    board { boardMarked = pos:(boardMarked board) }

Pattern matching

openedAndMarked :: Board -> ([Pos], [Pos])
openedAndMarked 
    (Board { boardOpened=o, boardMarked=m }) = o, m

Polymorfizmus

Typy polymorfizmu

Príklady

Prekrývanie funkcií a operátorov

int times(int x, int y) {
    return x * y;
}
String times(int n, String s) {
    return StringUtils.repeat(s, n);
}

Typové parametre

Podtypy

Typové triedy

class Eq a where
    (==) :: a -> a -> Bool
    (/=) :: a -> a -> Bool

instance Eq Point where 
    (Point x1 y1) == (Point x2 y2)  =  x1 == x2 && y1 == y2
    a /= b  =  not (a == b)

Predvolená implementácia

class Eq a where
    (==), (/=) :: a -> a -> Bool
    x /= y  =  not (x == y)
    x == y  =  not (x /= y)

Príklad

elem :: ?
elem x []     = False
elem x (y:ys) = x==y || (elem x ys)

Typ?

elem :: a -> [a] -> Bool
elem x []     = False
elem x (y:ys) = x==y || (elem x ys)

Kontext

elem :: (Eq a) => a -> [a] -> Bool
elem x []     = False
elem x (y:ys) = x==y || (elem x ys)

Kontext inštancie

instance Eq a => Eq (List a) where
    Nil == Nil              =  True
    Cons x xs == Cons y ys  =  x == y && xs == ys
    _ == _                  =  False

Dedičnosť

class (Eq a) => Ord a where
    compare              :: a -> a -> Ordering 
    (<), (<=), (>=), (>) :: a -> a -> Bool
    max, min             :: a -> a -> a

Haskell vs Java

Nie elem :: Eq -> [Eq] -> Bool,
ale elem :: (Eq a) => a -> [a] -> Bool

Implementácia inštancie

Štandartné typové triedy pre čísla

Ďalšie štandartné typové triedy

Typové triedy vyššieho rádu

class Functor f where
    fmap :: (a -> b) -> f a -> f b
instance Functor List where
  fmap op Nil       = Nil
  fmap op (Cons x xs) = Cons (op x) (fmap op xs)

Druhy (kinds)

Functor

class Functor f where
    fmap :: (a -> b) -> f a -> f b
instance Functor List where
  fmap op Nil       = Nil
  fmap op (Cons x xs) = Cons (op x) (fmap op xs)

Ďalšie typové triedy

elem v skutočnosti

class Foldable t where
    ...
    elem :: Eq a => a -> t a -> Bool
    elem = any . (==)
    ...

Automatické odvodenie

data Shape = Circle Point Double
           | Rectangle Point Point
           deriving (Eq, Ord, Show)

Typy v jazyku Haskell