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

Lambda calculus, Type theory, Formal semantics, Program analysis

Prev     Next     All lectures           Code

Functions and Type Inferencing

f1 x = y !! length x
 where
  y = [False] ++ 
      [ e || a 
      | e <- y
      | a <- x ]

f2 x g = g y 
 where
  y = [ e == 0 | e <- x ]

v1 = f2 [2,3,4,0,4] f1

f3 x = y !! length x
 where
  y = ["no"] ++ 
      [ if e == "yes" || a then "yes" else "no"
      | e <- y
      | a <- x ]

v2 = f2 [2,3,4,0,4] f3

f4 x = y !! length x
 where
  y = [0] ++ 
      [ if e == 1 || a then 1 else 0 
      | e <- y 
      | a <- x ]

v3 = f2 [2,3,4,0,4] f4

f5::Num a => [a] -> ([Bool] -> a) -> a
f5 x g = g y 
 where
  y = [ e == 0 | e <- x ]

v4 = f5 [2,3,4,0,4] f4
  -   Type checking is done at compile time (static checking). Types can be inferred from operations used. If functions are first class they need to have types. The inferred type for f1 is
 f1::[Bool] -> Bool
This function logically 'or's the booleans of a list. Function f2 determines whether some number in a list is 0. Function g is expected to be a function of type g::[Bool] -> Bool. The inferred type for f2 is
 f2::Num a => [a] -> ([Bool] -> t) -> t
Notice the t instead of something concrete like Bool. The value of v1 is True.

Function f3 is similar to f1 except it operates on yes/no strings. Its inferred type is

 f3::[Bool] -> [Char] 
It may be used as the second argument in f2. For example, the value of v2 is "yes".

Function f4 is similar to f1 except it operates on 0/1 numbers. Its inferred type is

 f4::Num a => [Bool] -> a
and it may also be used as second argument to f2. For example, v3 is 1.

Function f5 is a redefinition of f2 except with a stricter type, as shown. Now only f4 can be used as second argument to f5. For example, v4 is 1. But

 v5 = f5 [2,3,4,0,4] f3 
fails with
  No instance for (Num [Char]) arising from the literal `4'