HOW TO BE MORE PRODUCTIVE Graham Hutton and Mauro Jaskelioff Streams A stream is an infinite sequence of values: 0 1 2 3 4 ... The type of streams is co-inductively defined: codata Stream A = A Stream A 1 Defining Streams Streams can be defined by recursive equations: ones :: Stream Nat ones = 1 ones nats :: Stream Nat nats = 0 map (+1) nats 2 This Talk How do we ensure such equations make sense, i.e. that they produce well-defined streams? loop :: Stream A loop = tail loop A new approach, based upon a representation theorem for contractive functions. 3 Fixed Points The starting point for our approach is the use of explicit fixed points. For example: ones = 1 ones can be rewritten as: ones = fix body body xs = 1 xs fix f = f (fix f) 4 The Problem Given a function on streams f :: Stream A Stream A when does fix f :: Stream A makes sense, i.e. produce a well-defined stream? 5 Contractive Functions Adapting an idea from topology, let us say that a function f on streams is contractive iff: xs =n ys Equal for the first n elements. f xs =n+1 f ys Equal for one further element. 6 Banach’s Theorem Every contractive function f :: Stream A c Stream A has a unique fixed point fix f :: Stream A and hence produces a well-defined stream. 7 This theorem provides a semantic means of ensuring that stream definitions are valid. 8 Example The function (1 ) is contractive: xs =n ys 1 xs =n+1 1 ys Hence, it has a unique fixed point, and ones = fix (1 ) is a valid definition for a stream. 9 Example The function tail is not contractive: xs =n ys tail xs =n+1 tail ys Hence, Banach’s theorem does not apply, and loop = fix tail is rejected as an invalid definition. 10 Questions Does the converse also hold - every function with a unique fixed point is contractive? What does contractive actually mean? What kind of functions are contractive? 11 Key Idea If we view a stream as a time-varying value x0 x1 x2 x3 x4 ... then a function on streams is contractive iff Its output value at any time only depends on input values at strictly earlier times. 12 This result simplifies the process of deciding if a function is contractive. 13 Examples (1 ) tail Each output depends on the input one step earlier in time. Each output depends on the input one step later in time. 14 Generating Functions This idea is formalised using generating functions, which map finite lists to single values: [A] B All earlier input values. The next output value. 15 Representation Theorem Every contractive function can be represented by a generating function, and vice versa: rep Stream A c Stream B [A] B ge n Moreover, rep and gen form an isomorphism. 16 This theorem provides a practical means of producing streams that are well-defined. 17 Example g g [] :: [Nat] Nat = 1 g (x:xs) = x ones :: Stream Nat ones = fix (gen g) Generator for ones. Guaranteed to be well-defined. 18 Example g g [] :: [Nat] Nat = 0 g (x:xs) = x+1 nats :: Stream Nat nats = fix (gen g) Generator for nats. Guaranteed to be well-defined. 19 Example g :: [Nat] Nat g [] = 0 g [x] = 1 Generator for fibs. g (x:y:xs) = x+y fibs :: Stream Nat fibs = fix (gen g) Guaranteed to be well-defined. 20 Summary Generating functions are a sound and complete representation of contractive functions; Gives a precise characterisation of the class of functions that are contractive; Provides a simple but rather general means of producing well-defined streams. 21 Ongoing and Further Work Generalisation to final co-algebras; Other kinds of generating functions; Relationship to other techniques; Improving efficiency. 22