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

Lambda calculus, Type theory, Formal semantics, Program analysis

    Prev     Next     All lectures           Code

Function Syntax

   
f1 x = x+10
  -   Ex: (f1 10) is 20.
Inferred type is f1::Num a => a -> a
 
f2 x y = x+y
  -   Ex: (f2 10 20) is 30.
Inferred type is f2::Num a => a -> a -> a
 
f3 x y = x++y
  -   Ex: (f3 [10] [20]) is [10,20].
Inferred type is f3::[a] -> [a] -> [a]
 
f4 1 = 'A'
f4 2 = 'B'
f4 3 = 'C'
f4 x = 'Z'
  -   Ex: (f4 1) is 'A', (f4 10) is 'Z'.
Inferred type is f4::Num a => a -> Char
Pattern matches on the left, result is on the right
 
f5 ([]) = []
f5 (a:[]) = [a]
f5 (a:b:c:x) = x 
f5 (a:x) = x
  -   Ex: (f5 []) is [],
(f5 [1]) is [1],
(f5 [1,2,3,4,5]) is [4,5], (f5 [1,2,3]) is [],
(f5 [1,2]) is [2].
Inferred type is f5::[a] -> [a]
 
f6 bmi  
  | bmi <= 18.5 = "underweight"  
  | bmi <= 25.0 = "normal"  
  | bmi <= 30.0 = "overweight"  
  | otherwise   = "obese"  
  -   Guards
Ex: (f6 20) is "underweight",
(f6 25) is "normal",
(f6 28) is "overweight",
(f6 33) is "obese".
Inferred type is f6::(Ord a, Fractional a) => a -> [Char]
 
f7 r h = 
  let sideArea = 2 * pi * r * h  
      topArea = pi * r ^2  
  in  sideArea + 2 * topArea 
  -   let <bindings> in <expression>
Ex: (f7 2.3 11.1) is 193.6477711672748,
Inferred type is f7::Floating a => a -> a -> a
 
f8 xs = 
  [bmi | (w,h) <- xs, let bmi = w/h^2]
  -   let <bindings> in <expression>
Ex: (f8 [(88,175)]) is [2.87..e-3],
Inferred type is f8::Fractional t => [(t,t)] -> [t]
 
isInt x = x == fromInteger (round x)
f9 = [floor x|x <-[1..200], isInt(sqrt(x))]

  -   The output stream gets only integers from 1 to 200 whose square roots are integers. Ex: f9 is [1,4,9,16,25,36,49,64,81,100,121,144,169,196]
Inferred type: f9::[Integer]
Inferred type: isInt::RealFrac a => a -> Bool
Inferred type: sqrt::Floating a => a -> a
Inferred type: round::(Integral b, RealFrac a) => a -> b
Therefore x must be regarded as a Double so it can be used by sqrt and isInt must allow Double as input but round outputs Integer so fromInteger is needed as a wrapper. Also, since x is now a Double, floor x is used to output Integer values.
 
f10 func lst = map func lst
  -   Example of map: apply f to all elements in lst
Ex: (f10 head [[1,2,3],[4,5,6],[7,8,9]]) is [1,4,7],
Inferred type is f10::(a -> b) -> [a] -> [b]
 
f11 lst = map (+ 3) lst
  -   (+) is curried - (+ 3) returns a function of one argument
Ex: (f11 [1,2,3]) is [4,5,6],
Inferred type is f11::Num a => [a] -> [a]
 
f12 func lst = filter func lst
  -   Example of filter: allow x in lst only if (f x) is True
Ex: (f12 odd [1..10]) is [1,3,5,7,9],
Inferred type is f12::(a -> Bool) -> [a] -> [a]
 
f13 p lst = takeWhile p lst
  -   Example of takeWhile: take x in lst as long as (p x) is True
Ex: (f13 (< 10) [1..]) is [1,2,3,4,5,6,7,8,9],
Inferred type is f13::(a -> Bool) -> [a] -> [a]