Kihagyás

10. gyakorlat

Data, type

Kulcsszó Mi ez? Szintax Példa szintax
type szinonímája egy típusnak type TipusMasNeven = Tipus type Name = String
data teljesen új (saját) típus data TipusNev = Konstruktor1 stb. data Complex = C Integer Integer

Példa: Fruit

data Fruit = Apple Integer
           | Peach Integer
           | Grape Integer deriving Show

sumFruit :: [Fruit] -> (Integer, Integer, Integer)
sumFruit [] = (0,0,0)
sumFruit ((Apple i):xs) = (apples+i, peaches, grapes)
    where
        (apples, peaches, grapes) = sumFruit xs
sumFruit ((Peach i):xs) = (apples, peaches+i, grapes)
    where
        (apples, peaches, grapes) = sumFruit xs
sumFruit ((Grape i):xs) = (apples, peaches, grapes+i)
    where
        (apples, peaches, grapes) = sumFruit xs

Példa: Wrap

-- ZH gyanús
data V = Wrap (Integer -> Integer) Integer

eval :: V -> Integer
eval (Wrap f n) = f n

Példa: feljavított head (MaybeInt, MaybeChar)

-- head

{-
head' :: [a] -> a
head' (x:_) = x
head' [] = -- Ó jaj!!!
-}

-- head with MaybeInt

data MaybeInt = NoInt | JustInt Int deriving Show

safeHead1 :: [Int] -> MaybeInt
safeHead1 (x:_) = JustInt x
safeHead1 [] = NoInt

-- head with MaybeChar

data MaybeChar = NoChar | JustChar Char deriving Show

safeHead2 :: [Char] -> MaybeChar
safeHead2 (x:_) = JustChar x
safeHead2 [] = NoChar

Ennek a általánosított változata: Maybe

data Maybe a = Nothing | Just a deriving Show

safeHead :: [a] -> Maybe a
safeHead (x:_) = Just x
safeHead [] = Nothing

Példa: Maybe összeadás

add :: Num a => Maybe a -> Maybe a -> Maybe a
add (Just a) (Just b) = Just $ a + b
add _        _        = Nothing

Példa: Maybe kompozíció

maybeComp :: (b -> Maybe c) -> (a -> Maybe b) -> a -> Maybe c
maybeComp f g a = helper f (g a)
    where
        helper :: (b -> Maybe c) -> Maybe b -> Maybe c
        helper f Nothing = Nothing
        helper f (Just b) = f b

Példa: Either

data Either a b = Left a | Right b

eitherComp :: (b -> Either String c) -> (a -> Either String b) -> a -> Either String c
eitherComp f g a = helper f (g a)
    where
        helper :: (b -> Either String c) -> EitherString b -> Either String c
        helper f (Right b ) = f b
        helper f (Left str) = Left str
        -- helper f x@(Left str) = x    -- ez így nem jó (hiába tűnik ugyanannak), más a típusa

Példa: MaybeComp, másképp

case:

case ... of
    eset1 -> függvény1
    eset2 -> függvény2
    eset3 -> függvény3
maybeComp2 :: (b -> Maybe c) -> (a -> Maybe b) -> a -> Maybe c
maybeComp2 f g a = case g a of
    Nothing -> Nothing
    Just b -> f b

Példa: Lista

-- data [] a = [] | a : [a]
data List a = Cons a (List a) | Nil
infixr 5 `Cons`

instance Show a => Show (List a) where
    show Nil = "[]"
    show (Cons x xs) = "[" ++ show x ++ showRest xs where
        showRest Nil = "]"
        showRest (Cons y ys) = ", " ++ show y ++ showRest ys

Példa: map, saját listán

mapList :: (a -> b) -> List a -> List b
mapList _ Nil = Nil
mapList f (x `Cons` xs) = f x `Cons` mapList f xs

Példa: find

find1 :: (a -> Bool) -> [a] -> Maybe a
find1 _ [] = Nothing
find1 p (x:xs)
    | p x       = Just x
    | otherwise = find1 p xs

Példa: lookup

lookup1 :: Eq a => a -> [(a, b)] -> Maybe b
lookup1 _ [] = Nothing
lookup1 x ((a, b): xs)
    | a == x    = Just b
    | otherwise = lookup1 x xs

lookup2 :: Eq a => a -> [(a, b)] -> Maybe b
lookup2 x xs = case find1 (\(a, b) -> a == x ) xs of
    Nothing     -> Nothing
    Just (a, b) -> b