CSC302 2006S, Class 34: Haskell (1): The Basics
Admin:
* More Prolog?
* No reading for Wednesday
* Presentation proposals due Wednesday.
* Desired form for final?
* Take-home portion of final distributed Monday of 14th week, due Tuesday of finals week at 9 a.m.
* Missing: Alex (sick)
* Late: Dimitar, Mark
Overview:
* An Introduction to Haskell.
* Haskell Syntax.
* Types in Haskell.
* Patterns in Haskell.
Haskell:
* Haskell is a functional language
* Typeful
* Compile-time typing
* Type checking of expressions
* User typing
* User-declared types
* Lazy - Only evaluates "needed" subexpressions
* Pure - No side effects ; If you apply the same function to the same argument, you get the same value
(random 5) ; (read)
* Patterned - You can define functions with patterns
* Syntactic issues
* Which provides multiple mechanisms for function definition
* And multiple syntaxes for other things
* Nested comments
* Haskell is a committee-designed lazy functional language
* Response to:
* lots of different languages, few common designs
* need a language to "sell" to the broader world
* response to commercial nature of most popular lazy func. language
* Like many committee-designed languages, somewhat kitchen-sink-ish
* Haskell is traditionally compiled, but may be interepreted
* MathLAN: ghci
/Syntax/
* Generally, uses prefix notation
function op1 op2 op3 ... opn - Means apply function to operands
* Supports infix notation when 'appropriate'
* Arithmetic operations
* List operations
* (Your own operations)
* Capitalization significant
* Uppercase: Types, Constructors ; distinguish by context
* Lowercase: variables, functions ; distinguish by context
* Multiple forms for function definition
* Simple
name op1 op2 op3 ... opn = body
e.g.
fact n = if (n == 0) 1 (n * (fact (n-1)))
* Lambda based
name = \op1 op2 op3 ... opn -> body
fact = \n -> if (n == 0) 1 (n * (fact (n-1)))
* Pattern based (using constants in the lhs)
name op1 op2 op3 ... opn = body
fact 0 = 1
fact n = n * (fact (n - 1))
* Typing:
* Programmer can declare types
* System can infer types
/How do we determine need?/
* For simple and lambda-based: You don't need the params, so just replace by rhs (substituting as appropriate)
* For built-in operations: Depends on the operation
* IF "needs" its first parameter
* + "needs" both parameters (I think)
* cons "needs" neither parameter
* Pattern-based: Use the first constant in the first definition
* Use of patterns plus laziness
iif True x y = x
iif False x y = y
silly True x = x
silly x False = False
Pure logic: Order of evaluation should be "whatever is right"
Haskell: Since the first def'n of silly uses True in the arg 1, we valuate the first argument first
In "pure" logic, silly nonterminating False = False
In Haskell, silly nonterminating False does not terminate
nonterminating = nonterminating
Does this permit ambiguous definitions?
silly True x = x
silly x False = True
* Yes, if we treat the equations logically
* No, if we admit the sequencing