【问题标题】:Railway Oriented Programming - function output not passing through面向铁路的编程 - 函数输出不通过
【发布时间】: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#


    【解决方案1】:

    如果你看文章,算子有定义

    let (>=>) switch1 switch2 x = 
        match switch1 x with
        | Success s -> switch2 s
        | Failure f -> Failure f 
    

    正确翻译成你的变量时是:

    let (>=>) switch1 switch2 input =
      match switch1 input with
      | Success s -> switch2 s
      | Failure f -> Failure f
    

    您从未真正使用过Success 中的s,因此相同的输入只会不断通过。

    仔细检查&gt;=&gt; 的类型会发现这个问题,因为当switch1switch2 应该有不同的类型时,它们会给出相同的类型。

    【讨论】:

    • 呃,我真傻!我没有复制和粘贴他的代码,而是自己输入(为了让我停下来想一想)。我一定是看错了他的代码,打错了东西。感谢您的更正和解释。
    猜你喜欢
    • 2019-10-08
    • 2016-06-26
    • 2021-12-03
    • 1970-01-01
    • 1970-01-01
    • 2016-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多