F# 函数式编程之 - 习题答案

原文 https://fsharpforfunandprofit.com/posts/computation-expressions-bind/

原文的末尾有一道练习题:

let strToInt str = ???

let stringAddWorkflow x y z = 
    yourWorkflow 
        {
        let! a = strToInt x
        let! b = strToInt y
        let! c = strToInt z
        return a + b + c
        }    

// test1
let good = stringAddWorkflow "12" "3" "2"
let bad = stringAddWorkflow "12" "xyz" "2"

let strAdd str i = ???
let (>>=) m f = ???

// test2
let good = strToInt "1" >>= strAdd "2" >>= strAdd "3"
let bad = strToInt "1" >>= strAdd "xyz" >>= strAdd "3"

题目要求补充上面代码的未完成部分,使代码正确运行。

做这一道练习题,需要先学习本系列前面的文章以及相关原文。

以下是我的解答:

let strToInt str =
    try
        Ok (int str)
    with
    | _ -> Error "not a number"

type MaybeBuilder() =
    member this.Bind(x, f) = Result.bind f x
    member this.Return(x) = Ok x

let maybe = new MaybeBuilder()

let stringAddWorkflow x y z = 
    maybe
        {
        let! a = strToInt x
        let! b = strToInt y
        let! c = strToInt z
        return a + b + c
        }    

let strAdd str i =
    maybe {
        let! a = strToInt str
        return a + i
    }

let (>>=) m f = Result.bind f m

// test
let printA x = x |> printfn "%A"

printA <| stringAddWorkflow "12" "3" "2"
printA <| stringAddWorkflow "12" "xyz" "2"

strToInt "1" >>= strAdd "2" >>= strAdd "3" |> printA
strToInt "1" >>= strAdd "xyz" >>= strAdd "3" |> printA
posted @ 2020-12-14 16:20  cmdOptionKana  阅读(57)  评论(0编辑  收藏