Outline 1 2 3 4
What is Haskell? Haskell is a functional programming language. Characteristics functional non-strict ( lazy ) pure (no side effects*) strongly statically typed available compiled and interpreted
Notes to run a program: evaluate an expression (probably a function call) side-effects only occur through the IO Monad we ll get there eventually! main ways to run with ghc: compile module file(s) with ghc need a Main module with main method of type IO () creates stand-alone executable interpret module file(s) with ghci loads modules can execute expressions interactively define things (rare syntax differences)
More Details all operators are actually functions! runs as infix: 2 + 3 parenthesize to make them prefix: (+) 2 3 function call: just place params after function name example: div n 5 can make a function infix. Surround with back-ticks: 21 div 5
More Details... indentation is significant! identifiers are case-significant. Letters, numbers, underscore, quote allowed. values start with a lower-case letter or underscore types start with upper-case
Some basic list operations: head (first element) tail (all elements after first) last (last element) init (all but last element) even more: reverse, take, drop, elem,... look to hoogle to find a function by its type!
... Syntax syntax: [ ] s, commas empty list: [ ] Semantics monomorphic sequence of values not an array! constructed as a head and tail
... Basic Binary Operations concatenation: ++ only between two lists cons: : an element and a list
infinite lists possible due to lazy evaluation can create with [n..] syntax can create via function. Example: ones = 1:ones some provided definitions: repeat, cycle
Some other structures we ll want/need soon if-then-else expression (not a statement!) if expr then expr else expr let expression let pattern = expr in expr Strings are truly just lists of characters ([Char]) type String = [Char]
Haskell lists example lists monomorphic, unbounded length xs = [1,1,2,3,5,8,13] ys = [1..] zs = [True, False, False, True] empty = [] twod = [[1,2,3],[4,5,6]]
Haskell tuples specific length (2 or more), each spot has its own type comma-separated values in parentheses example tuples candidate = ("Dave",35,True) valvarpair = ("x",5) bigpair = (1,5,"yes", [1,2,3], (), (0,0))
Haskell unit the non-value value: () Bool True and False Abstract Data Types user-defined type. Defines multiple constructors and their aggregated values Some Haskell types are actually just ADTs: e.g. Bool,.
Abstract Data Types define a new type by naming each way to make such a value (each called a constructor) each constructor can have some finite number of attributes of specific types supplied as arguments to constructor pattern matching is readily available over this newly defined type
ADTs Example Data Structure data Eether = This Bool That Int Int Int Notes This and That are constructors the Bool and Int values will be arguments to the constructor This :: Bool -> Eether That :: Int -> Int -> Int -> Eether
Type Variables types can be parameterized over type variables. they provide parametric polymorphism. (Think of forall s from predicate logic). Java s generics are another example of parametric polymorphism specific uses of things at these types may be at more concrete versions of these types. map::(a->b)->[a]->[b], but (map ord)::[char]->[int]
Type Variables... represented within types via lowercase letters implicitly created by usage (no need for forall s, as in forall a b. a->b->(a,b) ) only in scope during that type expression names only useful to make them distinct from one another Int -> a -> [a] could be written: Int -> asdf -> [asdf] very powerful means to quickly write functions that work over any type while still maintaining type checking actions between occurrences of the particular concrete type at which we use the function
ADTs and Type Variables parameterizing a data type: -- not parameterized data IntOrBool = IBI Int IBB Bool -- parameterized over a, b data Either a b = Left a Right b Notes we could get rid of IntOrBool: just use Either Int Bool.
Pattern-Matching Any ADT, with its constructors, can be pattern-matched: at the beginning of a function as a case-expression anywhere expressions are allowed function pattern-matching: maximum (x:xs) = max x (maximum xs) maximum [x] = x maximum [ ] = error "empty list! no maximum." foo (IBI n) = n foo (IBB True ) = 1 foo (IBB False) = 0
Pattern-Matching (continued) case-expression my_if b x y = case b of True -> x False -> y mylen xs = case xs of (v:vs) -> 1 + (my_len vs) (v:[]) -> 1 [] -> 0 Note: the (v:[]) row wasn t necessary, but works.
Types, Everywhere! Haskell Types Haskell has static types. Haskell infers basically all types we can still ascribe types via the :: operator. example: 5::Int When would we need to? users can create their own types via ADTs type synonyms may be constructed