<Query Kind="FSharpProgram" />

let unit t = async.Return t
//let unit t = async {return t}

let unit1 = Async.RunSynchronously

let m = async { return 3 }
let n = async { return! m }
printfn "%A %A" (unit1 m) (unit1 n)

let h t = t + 1         
let f t = unit (t+1)     
//let f t = async { return t+1 }

//let map h m = 
//    let t = Async.RunSynchronously m
//    async { return h t } // async.Return (h t)

let map h m = async {
    let! t = m
    return h t  // return! async {return h t}
    }

//let bind f m = 
//    let t = Async.RunSynchronously m
//    f t

let bind f m = async {
    let! t = m
    return! f t
    }

printfn "%A %A" (unit1 (map h m)) (unit1 (bind f m))

let flat m2 =  // bind id m2
    async { 
        let! t = m2
        return! t  
    }

let m2 = async { return async { return 7 } }
printfn "%A" (unit1 (flat m2))



