<Query Kind="FSharpProgram" />

let h t = t + 1

let f t = [t; t+1]

// ---

let unit t = [t]

// ---

let map h m = List.map h m 

let x = map h [3; 7]
printfn "x: %A" x

let x' = map f [3; 7]
printfn "x': %A" x'

let bind f m = List.collect f m
let z = bind f [3; 7]
printfn "z: %A" z

let flat m2 = List.concat m2

let y = flat [[3; 4]; [7; 8]]
printfn "y: %A" y

// ---

let map' h m = bind (h >> unit) m 

let flat' m2 = bind id m2

// ---
printfn ""

let m = [3; 7]

let b = map h m

let b' = map' h m

printfn "map: %A => %A" m b
printfn "map': %A => %A" m b'

// ---
printfn ""

let m2 = [[3; 4]; [7; 8]]

let c = flat m2

let c' = flat' m2

printfn "flat: %A => %A" m2 c
printfn "flat': %A => %A" m2 c'

// ---
printfn ""

let bind' f m = map f m |> flat

//let m = [3; 7]

let d = bind f m

let d' = bind' f m

printfn "bind: %A => %A" m d
printfn "bind': %A => %A" m d'

// ---