<Query Kind="FSharpProgram" />

// ---

printfn "\r\npoor man's map"

let s = seq [10; 20; 30; 40; 50]
let z = Seq.map (fun t -> t*2) s
printfn "z=%A" z

let mymap f s = seq { for t in s do yield f t }
// mymap : f:('a -> 'b) -> s:seq<'a> -> seq<'b>
// let mymap<'a, 'b> (f:'a -> 'b) (s: seq<'a>) : seq<'b> = seq { for t in s do yield f t }

let z2 = mymap (fun t -> t*2) s
printfn "z2=%A" z2

let f = s |> Seq.map (fun t -> t % 4 = 0)
printfn "f=%A" f

let g = s |> Seq.filter (fun t -> t % 4 = 0)
printfn "g=%A" g

let m4 t = t % 4 = 0

let h = s |> Seq.filter m4
printfn "h=%A" h

// ---

let inc1 x = x + 1 // int -> int

let g0 = { 10..10..30 } // 10 20 30

let seqinc1 = Seq.map inc1

let g1 = seqinc1 g0
printfn "g1 = %A" g1

let inc2 x = Seq.singleton (x+1) // int -> seq<int>

let seqinc2 = Seq.collect inc2

let g2 = seqinc2 { 10..10..30 } // [10; 20; 30] [|10; 20; 30|]
printfn "g2 = %A" g2

// ---

printfn "\r\nsequences: virtual vs physical (lists, arrays)"

let u = seq { yield 10; yield 20; yield 30 }
printfn "%A" u

let mutable x = 10
let v = seq { yield x; yield x; yield x }
let w = [| x; x; x |]
printfn "%A" v

for t in v do
    printfn "%d" t

for t in v do
    printfn "%d" t
    x <- x + 1

for t in w do
    printfn "%d" t
    x <- x + 1

// ---

printfn "\r\ninfinite sequence"

let infinity = seq { 
            let y = ref 1
            while true do
                yield !y
                y := !y + 1
            }

for t in (Seq.take 10 infinity) do
    printfn "%d" t
 
let infinity2 = infinity |> Seq.filter (fun t -> t % 3 = 0)
for t in (Seq.take 10 infinity2) do
    printfn "%d" t
 
// ---

let s0 = seq { yield 10; yield 20; yield 30; yield 40; yield 50}
printfn "s0=%A" s0

let r1 = Seq.map (fun t -> t + 1) s0
printfn "r1=%A" r1

let r2 = Seq.fold (fun a t -> a @ [t+1]) [] s0
printfn "r2=%A" r2

//[] @ [11] = [11]
//[11] @ [21] = [11; 21]
//[11; 21] @ [31] = [11; 21; 31]