【发布时间】:2016-03-06 23:06:42
【问题描述】:
我一直在努力通过this article on ROP,并到达“将简单函数转换为面向铁路的编程模型”部分,他解释了如何将其他类型的函数融入其中模型。
他举了一个想清理邮箱地址的例子(函数名和我英文不一样!)...
let cleanEmail person =
printfn "Cleaning email for \"%s\"" person.Name
let newPerson = { person with Email = person.Email.Trim().ToLower() }
printfn " email is now \"%s\"" newPerson.Email
newPerson
我添加了一些 printfn 以查看发生了什么。这个函数工作得很好,因为如果我向它传递一个带有大写字母和/或前导/尾随空格的电子邮件的输入,输出是一个带有干净的小写电子邮件地址的值......
let shouter = { Name = "Jim"; Email = " JIM@SHOUT.com "}
cleanEmail shouter
给出输出...
Cleaning email for "Jim"
email is now "jim@shout.com"
val it : Request = {Name = "Jim";
Email = "jim@shout.com";}
但是,如果我将此函数包装在一个开关中,并将其插入验证函数链中,则会使用原始电子邮件地址。例如,使用这样的验证函数...
let validateNameNotBlank person =
printfn "Validating name not blank for \"%s\"" person.Name
if person.Name = "" then Failure "Name must not be blank"
else Success person
...这样的运算符...
let (>=>) switch1 switch2 input =
match switch1 input with
| Success s -> switch2 input
| Failure f -> Failure f
...像这样绑在一起...
let validate =
validateNameNotBlank
>=> validateNameLength
>=> switch cleanEmail
>=> validateEmail
...然后当我将喊叫者传进来时,我会得到以下内容...
Validating name not blank for "Jim"
Validating name length for "Jim"
Cleaning email for "Jim"
email is now "jim@shout.com"
Validating email for "Jim" ( JIM@SHOUT.com )
val it : Result<Request,string> = Success {Name = "Jim";
Email = " JIM@SHOUT.com ";}
从我输入的 printfn 可以看出,cleanEmail 函数正在清理邮件,但是输出显示原来的邮件被传递给了链中的下一个函数。
我在这里错过了什么?
【问题讨论】:
标签: f#