20-CS-4003-001 Organization of Programming Languages Fall 2017
Functors

Lambda calculus, Type theory, Formal semantics, Program analysis

Prev     Next     All lectures           Code

Basics

{- deriving other classes - all named types (String and Int here) must 
   already derive from Eq -  ops available: == /=, not available <, > -}
data Person = Person { firstName :: String  
                     , lastName :: String  
                     , age :: Int  
                     } deriving (Eq)

p4 = Person { firstName = "John", lastName = "Franco", age = 22 }
p5 = Person { firstName = "Jim", lastName = "Ravella", age = 25 }
p6 = Person { firstName = "John", lastName = "Franco", age = 22 }
p7 = Person { firstName = "John", lastName = "Franco", age = 21 }

x1 = (firstName p4) == (firstName p7)

lst = [p4,p5,p6,p7]

{- can be done because Person derives from Eq which is needed by elem -}
x2 = (Person "John" "Franco" 22) `elem` lst

{- Bool derives from Ord so compare can be used -}
x3 = compare True False
x4 = True < False

{- Note: (* 3) is a function so does not derive from Ord and (*3) < (*5) 
   is not allowed : even Just (*3) < Just (*4) is not allowed -}

{- Can derive from Enum because there are no type parameters, since there
   are seven values, can derive from Bounded, deriving from Eq and Ord
   give the values an order, increasing from left to right -}
data Day 
  = Sunday | Monday | Tuesday | Wednesday | Thursday | Friday | Saturday 
    deriving (Eq, Ord, Show, Read, Bounded, Enum)  

x5 = Monday < Tuesday
x6 = read "Saturday"::Day
x7 = compare Tuesday Monday

{- data Either a b =
       Left a | Right b 
       deriving (Eq, Ord, Read, Show) 
   If Left is used, contents are of type a, if Right is used contents 
   are of type b
   Note: now one can have a function return more than one type:
-}

x8 = Right 20  
x9 = Left "w00t"  

{- func :: (Integral a, Num a1) => a -> Either a1 [Char] -}
func x = if (even x) then Right "OK"; else Left 34

{- Another example
   fm :: Ord b => [b] -> Either [a] b 
-}
fm lst = 
    if (lst == []) then Left []
    else Right (last y)
      where
        y = (head lst):[ max a l | a <- y | l <- lst]

{- Without Left and Right
   fm1 :: Ord a => [[a]] -> [a] 
   because output must be a list of some type and y is a single element
   from the input list
-}
fm1 lst = 
    if (lst == []) then []
    else last y
      where
        y = (head lst):[ max a l | a <- y | l <- lst]

{- Another possibility - fm2 :: Ord a => [a] -> [a] -}
fm2 lst = 
    if (lst == []) then []
    else [last y]
      where
        y = (head lst):[ max a l | a <- y | l <- lst]