02157 Functional Programming - Sequencesmire/FSharpBook/SlidesCompressed/Lecture10.pdf · 02157...
Transcript of 02157 Functional Programming - Sequencesmire/FSharpBook/SlidesCompressed/Lecture10.pdf · 02157...
02157FunctionalProgram-
ming
Michael R. Hansen02157 Functional ProgrammingSequences
Michael R. Hansen
1 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Sequences (or Lazy Lists)
• lazy evaluation or delayed evaluation is the technique of delayinga computation until the result of the computation is needed.
Default in lazy languages like Haskell
It is occasionally efficient to be lazy.
A special form of this is Sequences, where the elements are notevaluated until their values are required by the rest of the program.
• a sequence may be infinitejust a finite part of a it is used in computations
Example:
• Consider the sequence of all prime numbers:2,3, 5, 7, 11,13,17,19,23, . . .
• the first 5 are 2,3, 5, 7,11Sieve of Eratosthenes
2 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Sequences (or Lazy Lists)
• lazy evaluation or delayed evaluation is the technique of delayinga computation until the result of the computation is needed.
Default in lazy languages like Haskell
It is occasionally efficient to be lazy.
A special form of this is Sequences, where the elements are notevaluated until their values are required by the rest of the program.
• a sequence may be infinitejust a finite part of a it is used in computations
Example:
• Consider the sequence of all prime numbers:2,3, 5, 7, 11,13,17,19,23, . . .
• the first 5 are 2,3, 5, 7,11Sieve of Eratosthenes
3 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Sequences (or Lazy Lists)
• lazy evaluation or delayed evaluation is the technique of delayinga computation until the result of the computation is needed.
Default in lazy languages like Haskell
It is occasionally efficient to be lazy.
A special form of this is Sequences, where the elements are notevaluated until their values are required by the rest of the program.
• a sequence may be infinitejust a finite part of a it is used in computations
Example:
• Consider the sequence of all prime numbers:2,3, 5, 7, 11,13,17,19,23, . . .
• the first 5 are 2,3, 5, 7,11Sieve of Eratosthenes
4 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Sequences (or Lazy Lists)
• lazy evaluation or delayed evaluation is the technique of delayinga computation until the result of the computation is needed.
Default in lazy languages like Haskell
It is occasionally efficient to be lazy.
A special form of this is Sequences, where the elements are notevaluated until their values are required by the rest of the program.
• a sequence may be infinitejust a finite part of a it is used in computations
Example:
• Consider the sequence of all prime numbers:2,3, 5, 7, 11,13,17,19,23, . . .
• the first 5 are 2,3, 5, 7,11Sieve of Eratosthenes
5 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Delayed computations
The computation of the value of e can be delayed by ”packing” it intoa function (a closure):
fun () -> e
Example:
fun () -> 3+4;;val it : unit -> int = <fun:clo@10-2>
it();;val it : int = 7
The addition is deferred until the closure is applied.
6 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Delayed computations
The computation of the value of e can be delayed by ”packing” it intoa function (a closure):
fun () -> e
Example:
fun () -> 3+4;;val it : unit -> int = <fun:clo@10-2>
it();;val it : int = 7
The addition is deferred until the closure is applied.
7 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Example continued
One can make it visible when computations are performed by use ofside effects:
let idWithPrint i = let _ = printfn "%d" ii;;
val idWithPrint : int -> int
idWithPrint 3;;3val it : int = 3
The value is printed before it is returned.
fun () -> (idWithPrint 3) + (idWithPrint 4);;val it : unit -> int = <fun:clo@14-3>
Nothing is printed yet.
it();;34val it : int = 7
8 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Example continued
One can make it visible when computations are performed by use ofside effects:
let idWithPrint i = let _ = printfn "%d" ii;;
val idWithPrint : int -> int
idWithPrint 3;;3val it : int = 3
The value is printed before it is returned.
fun () -> (idWithPrint 3) + (idWithPrint 4);;val it : unit -> int = <fun:clo@14-3>
Nothing is printed yet.
it();;34val it : int = 7
9 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Example continued
One can make it visible when computations are performed by use ofside effects:
let idWithPrint i = let _ = printfn "%d" ii;;
val idWithPrint : int -> int
idWithPrint 3;;3val it : int = 3
The value is printed before it is returned.
fun () -> (idWithPrint 3) + (idWithPrint 4);;val it : unit -> int = <fun:clo@14-3>
Nothing is printed yet.
it();;34val it : int = 7
10 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Sequences in F#
A lazy list or sequence in F# is a possibly infinite, ordered collectionof elements, where the elements are computed by demand only.
A natural number sequence 0, 1, 2, . . . is created as follows:
let nat = Seq.initInfinite (fun i -> i);;val nat : seq<int>
A nat element is computed by demand only:
let nat = Seq.initInfinite idWithPrint;;val nat : seq<int>
Seq.nth 4 nat;;4val it : int = 4
11 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Sequences in F#
A lazy list or sequence in F# is a possibly infinite, ordered collectionof elements, where the elements are computed by demand only.
A natural number sequence 0, 1, 2, . . . is created as follows:
let nat = Seq.initInfinite (fun i -> i);;val nat : seq<int>
A nat element is computed by demand only:
let nat = Seq.initInfinite idWithPrint;;val nat : seq<int>
Seq.nth 4 nat;;4val it : int = 4
12 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Sequences in F#
A lazy list or sequence in F# is a possibly infinite, ordered collectionof elements, where the elements are computed by demand only.
A natural number sequence 0, 1, 2, . . . is created as follows:
let nat = Seq.initInfinite (fun i -> i);;val nat : seq<int>
A nat element is computed by demand only:
let nat = Seq.initInfinite idWithPrint;;val nat : seq<int>
Seq.nth 4 nat;;4val it : int = 4
13 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Further examples
A sequence of even natural numbers is easily obtained:
let even = Seq.filter (fun n -> n%2=0) nat;;val even : seq<int>
Seq.toList(Seq.take 4 even);;0123456val it : int list = [0; 2; 4; 6]
Demanding the first 4 even numbers demands a computation of thefirst 7 natural numbers.
14 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Further examples
A sequence of even natural numbers is easily obtained:
let even = Seq.filter (fun n -> n%2=0) nat;;val even : seq<int>
Seq.toList(Seq.take 4 even);;0123456val it : int list = [0; 2; 4; 6]
Demanding the first 4 even numbers demands a computation of thefirst 7 natural numbers.
15 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Further examples
A sequence of even natural numbers is easily obtained:
let even = Seq.filter (fun n -> n%2=0) nat;;val even : seq<int>
Seq.toList(Seq.take 4 even);;0123456val it : int list = [0; 2; 4; 6]
Demanding the first 4 even numbers demands a computation of thefirst 7 natural numbers.
16 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Sieve of Eratosthenes
Greek mathematician (194 – 176 BC)
Computation of prime numbers
• start with the sequence 2, 3,4, 5, 6, ...select head (2), and remove multiples of 2 from the sequence
2
• next sequence 3, 5, 7,9, 11, ...select head (3), and remove multiples of 3 from the sequence
2, 3
• next sequence 5, 7, 11,13,17, ...select head (5), and remove multiples of 5 from the sequence
2,3, 5
•...
17 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Sieve of Eratosthenes
Greek mathematician (194 – 176 BC)
Computation of prime numbers
• start with the sequence 2, 3,4, 5, 6, ...select head (2), and remove multiples of 2 from the sequence
2
• next sequence 3, 5, 7,9, 11, ...select head (3), and remove multiples of 3 from the sequence
2, 3
• next sequence 5, 7, 11,13,17, ...select head (5), and remove multiples of 5 from the sequence
2,3, 5
•...
18 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Sieve of Eratosthenes
Greek mathematician (194 – 176 BC)
Computation of prime numbers
• start with the sequence 2, 3,4, 5, 6, ...select head (2), and remove multiples of 2 from the sequence
2
• next sequence 3, 5, 7,9, 11, ...select head (3), and remove multiples of 3 from the sequence
2, 3
• next sequence 5, 7, 11,13,17, ...select head (5), and remove multiples of 5 from the sequence
2,3, 5
•...
19 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Sieve of Eratosthenes in F# (I)
Remove multiples of a from sequence sq:
let sift a sq = Seq.filter (fun n -> n % a <> 0) sq;;val sift : int -> seq<int> -> seq<int>
Select head and remove multiples of head from the tail – recursively:
let rec sieve sq =Seq.delay (fun () ->
let p = Seq.nth 0 sqSeq.append
(Seq.singleton p)(sieve(sift p (Seq.skip 1 sq))));;
val sieve : seq<int> -> seq<int>
• Delay is needed to avoid infinite recursion
• Seq.append is the sequence sibling to @
• Seq.nth 0 sq gives the head of sq
• Seq.skip 1 sq gives the tail of sq
20 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Sieve of Eratosthenes in F# (I)
Remove multiples of a from sequence sq:
let sift a sq = Seq.filter (fun n -> n % a <> 0) sq;;val sift : int -> seq<int> -> seq<int>
Select head and remove multiples of head from the tail – recursively:
let rec sieve sq =Seq.delay (fun () ->
let p = Seq.nth 0 sqSeq.append
(Seq.singleton p)(sieve(sift p (Seq.skip 1 sq))));;
val sieve : seq<int> -> seq<int>
• Delay is needed to avoid infinite recursion
• Seq.append is the sequence sibling to @
• Seq.nth 0 sq gives the head of sq
• Seq.skip 1 sq gives the tail of sq
21 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Examples
The sequence of prime numbers and the n’th prime number:
let primes = sieve(Seq.initInfinite (fun n -> n+2));;val primes : seq<int>
let nthPrime n = Seq.nth n primes;;val nthPrime : int -> int
nthPrime 100;;val it : int = 547
Re-computation can be avoided by using cached sequences:
let primesCached = Seq.cache primes;;
let nthPrime’ n = Seq.nth n primesCached;;val nthPrime’ : int -> int
Computing the 700’th prime number takes about 8s; a subsequentcomputation of the 705’th is fast since that computation starts fromthe 700 prime number
22 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Examples
The sequence of prime numbers and the n’th prime number:
let primes = sieve(Seq.initInfinite (fun n -> n+2));;val primes : seq<int>
let nthPrime n = Seq.nth n primes;;val nthPrime : int -> int
nthPrime 100;;val it : int = 547
Re-computation can be avoided by using cached sequences:
let primesCached = Seq.cache primes;;
let nthPrime’ n = Seq.nth n primesCached;;val nthPrime’ : int -> int
Computing the 700’th prime number takes about 8s; a subsequentcomputation of the 705’th is fast since that computation starts fromthe 700 prime number
23 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Sieve of Eratosthenes using Sequence Expressions
Sequence expressions can be used for defining step-by-stepgeneration of sequences.
The sieve of Erastothenes:
let rec sieve sq =seq { let p = Seq.nth 0 sq
yield pyield! sieve(sift p (Seq.skip 1 sq)) };;
val sieve : seq<int> -> seq<int>
• By construction lazy – no explicit Seq.delay is needed
• yield x adds the element x to the generated sequence
• yield! sq adds the sequence sq to the generated sequence
•seqexp1seqexp2
appends the sequence of seqexp1 to that of seqexp2
24 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Sieve of Eratosthenes using Sequence Expressions
Sequence expressions can be used for defining step-by-stepgeneration of sequences.
The sieve of Erastothenes:
let rec sieve sq =seq { let p = Seq.nth 0 sq
yield pyield! sieve(sift p (Seq.skip 1 sq)) };;
val sieve : seq<int> -> seq<int>
• By construction lazy – no explicit Seq.delay is needed
• yield x adds the element x to the generated sequence
• yield! sq adds the sequence sq to the generated sequence
•seqexp1seqexp2
appends the sequence of seqexp1 to that of seqexp2
25 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Sieve of Eratosthenes using Sequence Expressions
Sequence expressions can be used for defining step-by-stepgeneration of sequences.
The sieve of Erastothenes:
let rec sieve sq =seq { let p = Seq.nth 0 sq
yield pyield! sieve(sift p (Seq.skip 1 sq)) };;
val sieve : seq<int> -> seq<int>
• By construction lazy – no explicit Seq.delay is needed
• yield x adds the element x to the generated sequence
• yield! sq adds the sequence sq to the generated sequence
•seqexp1seqexp2
appends the sequence of seqexp1 to that of seqexp2
26 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Sieve of Eratosthenes using Sequence Expressions
Sequence expressions can be used for defining step-by-stepgeneration of sequences.
The sieve of Erastothenes:
let rec sieve sq =seq { let p = Seq.nth 0 sq
yield pyield! sieve(sift p (Seq.skip 1 sq)) };;
val sieve : seq<int> -> seq<int>
• By construction lazy – no explicit Seq.delay is needed
• yield x adds the element x to the generated sequence
• yield! sq adds the sequence sq to the generated sequence
•seqexp1seqexp2
appends the sequence of seqexp1 to that of seqexp2
27 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Sieve of Eratosthenes using Sequence Expressions
Sequence expressions can be used for defining step-by-stepgeneration of sequences.
The sieve of Erastothenes:
let rec sieve sq =seq { let p = Seq.nth 0 sq
yield pyield! sieve(sift p (Seq.skip 1 sq)) };;
val sieve : seq<int> -> seq<int>
• By construction lazy – no explicit Seq.delay is needed
• yield x adds the element x to the generated sequence
• yield! sq adds the sequence sq to the generated sequence
•seqexp1seqexp2
appends the sequence of seqexp1 to that of seqexp2
28 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Sieve of Eratosthenes using Sequence Expressions
Sequence expressions can be used for defining step-by-stepgeneration of sequences.
The sieve of Erastothenes:
let rec sieve sq =seq { let p = Seq.nth 0 sq
yield pyield! sieve(sift p (Seq.skip 1 sq)) };;
val sieve : seq<int> -> seq<int>
• By construction lazy – no explicit Seq.delay is needed
• yield x adds the element x to the generated sequence
• yield! sq adds the sequence sq to the generated sequence
•seqexp1seqexp2
appends the sequence of seqexp1 to that of seqexp2
29 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Example: Catalogue search (I)
Extract (recursively) the sequence of all files in a directory:
open System.IO ;;
let rec allFiles dir =seq {yield! Directory.GetFiles dir
yield! Seq.collect allFiles (Directory.GetDirectories d ir) };;val allFiles : string -> seq<string>
whereSeq.collect: (’a -> seq<’c>) -> seq<’a> -> seq<’c>combines a ’map’ and ’concatenate’ functionality.
Directory.SetCurrentDirectory @"C:\mrh\Forskning\Cam bridge\";;let files = allFiles ".";;val files : seq<string>
Seq.nth 100 files;;val it : string = ".\ BOOK\ Satisfiability.fs"
Nothing is computed beyond element 100.
30 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Example: Catalogue search (I)
Extract (recursively) the sequence of all files in a directory:
open System.IO ;;
let rec allFiles dir =seq {yield! Directory.GetFiles dir
yield! Seq.collect allFiles (Directory.GetDirectories d ir) };;val allFiles : string -> seq<string>
whereSeq.collect: (’a -> seq<’c>) -> seq<’a> -> seq<’c>combines a ’map’ and ’concatenate’ functionality.
Directory.SetCurrentDirectory @"C:\mrh\Forskning\Cam bridge\";;let files = allFiles ".";;val files : seq<string>
Seq.nth 100 files;;val it : string = ".\ BOOK\ Satisfiability.fs"
Nothing is computed beyond element 100.
31 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Example: Catalogue search (II)
We want to search for files with certain extensions, e.g. as follows:
let funFiles=Seq.cache ( searchFiles (allFiles ".") ["fs";"fsi"]);;val funFiles : seq<string * string * string>
Seq.nth 0 funFiles;;val it: string * string * string= (".\ ", "CatalogueSearch", "fs")
Seq.nth 6 funFiles;;val it : string * string * string = (".\ BOOK\ ", "Curve", "fsi")
Seq.nth 11 funFiles;;val it : string * string * string
= (".\ BOOK\ ", "Satisfiability", "fs")
• a sequence in chosen so that the search is terminated when thewanted file is found
• a cached sequence in chosen to avoid re-computation
32 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Example: Catalogue search (II)
We want to search for files with certain extensions, e.g. as follows:
let funFiles=Seq.cache ( searchFiles (allFiles ".") ["fs";"fsi"]);;val funFiles : seq<string * string * string>
Seq.nth 0 funFiles;;val it: string * string * string= (".\ ", "CatalogueSearch", "fs")
Seq.nth 6 funFiles;;val it : string * string * string = (".\ BOOK\ ", "Curve", "fsi")
Seq.nth 11 funFiles;;val it : string * string * string
= (".\ BOOK\ ", "Satisfiability", "fs")
• a sequence in chosen so that the search is terminated when thewanted file is found
• a cached sequence in chosen to avoid re-computation
33 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Example: Catalogue search (III)
The search function ca be declared using regular expressions:
open System.Text.RegularExpressions ;;
let rec searchFiles files exts =let reExts = List.foldBack (fun ext re -> ext+"|"+re) exts ""let re = Regex (@"\G( \S * \\ )( [ˆ\\]+ )\.(" + reExts + ")$")seq {for fn in files do
let m = re.Match fnif m.Successthen let path = captureSingle m 1
let name = captureSingle m 2let ext = captureSingle m 3yield (path, name, ext) };;
val searchFiles : seq<string> -> string list-> seq<string * string * string>
• reExts is a regular expression matching the extensions
• The path matches the regular expression \S * \\
• The file name matches the regular expression [ˆ\\]+
• The function captureSingle can extract captured strings
34 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Example: Catalogue search (III)
The search function ca be declared using regular expressions:
open System.Text.RegularExpressions ;;
let rec searchFiles files exts =let reExts = List.foldBack (fun ext re -> ext+"|"+re) exts ""let re = Regex (@"\G( \S * \\ )( [ˆ\\]+ )\.(" + reExts + ")$")seq {for fn in files do
let m = re.Match fnif m.Successthen let path = captureSingle m 1
let name = captureSingle m 2let ext = captureSingle m 3yield (path, name, ext) };;
val searchFiles : seq<string> -> string list-> seq<string * string * string>
• reExts is a regular expression matching the extensions
• The path matches the regular expression \S * \\
• The file name matches the regular expression [ˆ\\]+
• The function captureSingle can extract captured strings
35 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Summary
• Anonymous functions fun () -> e can be used to delay thecomputation of e.
• Possibly infinite sequences provide natural and usefulabstractions
• The computation by demand only is convenient in manyapplications
It is occasionally efficient to be lazy.
The type seq<’a> is a synonym for the .NET typeIEnumerable<’a> .
Any .NET type that implements this interface can be used as asequence.
• Lists, arrays and databases, for example.
36 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Summary
• Anonymous functions fun () -> e can be used to delay thecomputation of e.
• Possibly infinite sequences provide natural and usefulabstractions
• The computation by demand only is convenient in manyapplications
It is occasionally efficient to be lazy.
The type seq<’a> is a synonym for the .NET typeIEnumerable<’a> .
Any .NET type that implements this interface can be used as asequence.
• Lists, arrays and databases, for example.
37 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Summary
• Anonymous functions fun () -> e can be used to delay thecomputation of e.
• Possibly infinite sequences provide natural and usefulabstractions
• The computation by demand only is convenient in manyapplications
It is occasionally efficient to be lazy.
The type seq<’a> is a synonym for the .NET typeIEnumerable<’a> .
Any .NET type that implements this interface can be used as asequence.
• Lists, arrays and databases, for example.
38 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Summary
• Anonymous functions fun () -> e can be used to delay thecomputation of e.
• Possibly infinite sequences provide natural and usefulabstractions
• The computation by demand only is convenient in manyapplications
It is occasionally efficient to be lazy.
The type seq<’a> is a synonym for the .NET typeIEnumerable<’a> .
Any .NET type that implements this interface can be used as asequence.
• Lists, arrays and databases, for example.
39 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012
02157FunctionalProgram-
ming
Michael R. Hansen
Summary
• Anonymous functions fun () -> e can be used to delay thecomputation of e.
• Possibly infinite sequences provide natural and usefulabstractions
• The computation by demand only is convenient in manyapplications
It is occasionally efficient to be lazy.
The type seq<’a> is a synonym for the .NET typeIEnumerable<’a> .
Any .NET type that implements this interface can be used as asequence.
• Lists, arrays and databases, for example.
40 DTU Informatics, Technical University of Denmark Sequences MRH 15/11/2012