什么是| f#中的符号?

时间:2017-06-28 20:52:48

标签: f#

我对函数式编程很陌生,我已经开始查看match语句的文档,并在我遇到的示例gitpages中剪切并粘贴到下面的问题:< / p>

let rec fib n =
    match n with
    | 0 -> 0
    | 1 -> 1
    | _ -> fib (n - 1) + fib (n - 2)

我理解let用于静态绑定,在这种情况下是一个名为fib的递归函数,它接受一个参数n。它试图匹配n与3个案例。如果它是0,1或其他任何东西。

我不明白在这种情况下调用|符号或使用它的原因是什么?我搜索的关于f-sharp管道的任何东西都把我带到了|>,这是f sharp中的管道特征。

在这种情况下,|用于什么?它是必需的还是可选的?什么时候应该而且不应该使用|

2 个答案:

答案 0 :(得分:6)

|符号用于F#中的多个内容,但在这种情况下,它用作match构造的案例的分隔符。

match构造允许您对某些输入进行模式匹配,并以不同方式处理不同的值 - 在您的示例中,您有0的一个案例,1的一个案例和一个案例所有其他价值观。

通常,match的语法如下所示:

match <input> with <case_1> | ... | <case_n>

每个<case>具有以下结构:

<case> = <pattern> -> <expression>

此处,|符号只是分隔模式匹配表达式的多个案例。然后,每个case都有一个模式和一个表达式,当输入与模式匹配时,它将被计算。

答案 1 :(得分:4)

为了扩展Tomas的优秀答案,以下是F#中|的各种用法:

匹配表达式

match expressions中,|将各种模式分开,正如托马斯指出的那样。虽然您可以将整个match表达式写在一行上,但是将每个模式写在一个单独的行上,排列|个字符是常规的,这样它们就形成了一个可视指示符。 match声明的范围:

match n with
| 0 -> "zero"
| 1 -> "one"
| 2 -> "two"
| 3 -> "three"
| _ -> "something else"

受歧视的联盟

Discriminated Unions(或者DUs,因为输入的时间要短很多)与样式中的match表达式非常相似:定义它们意味着列出可能性,而|是用于分离可能性。与match表达式一样,您可以(如果您愿意)在一行上写入DU:

type Option<'T> = None | Some of 'T

但除非您的DU只有两种可能性,否则通常最好将它写在多行上:

type ContactInfo =
    | Email of string
    | PhoneNumber of areaCode : string * number : string
    | Facebook of string
    | Twitter of string

在这里,|最终形成了一条垂直线,吸引了DU的可能性,并且非常清楚DU定义的结束位置。

活动模式

Active patterns也使用|来分隔各种可能性,但它们也包含在一对开始和结束的|字符中:

let (Even|Odd) n   = if n % 2 = 0 then Even else Odd  // <-- Wrong!
let (|Even|Odd|) n = if n % 2 = 0 then Even else Odd  // <-- Right!

活动模式通常以我刚刚显示的方式编写,|会立即出现在括号内,这就是为什么有些人会谈论&#34;香蕉剪辑&#34; (因为(||)对看起来像香蕉,如果你运用你的想象力)。但实际上,没有必要将(||)个字符拼写在一起:将括号与|字符分开的空格完全有效:

let (|Even|Odd|)   n = if n % 2 = 0 then Even else Odd  // <-- Right!
let ( |Even|Odd| ) n = if n % 2 = 0 then Even else Odd  // <-- ALSO right!

无关的事情

管道运算符|>和布尔运算符|||运算符的使用完全不同。 F#允许运算符为符号的任意组合,并且它们与看起来几乎相同的运算符具有非常不同的含义。例如,>=是标准运算符,表示&#34;大于&#34;。许多F#程序将定义自定义运算符>>=。但是虽然在F#核心库中没有定义>>=,但它具有标准含义,并且标准含义不是&#34;比&#34;大很多。相反,>>=是为bind函数编写运算符的标准方法。我现在还没有进入bind所做的事情,因为这个概念可以自行完成整个答案。但是,如果您对bind的工作原理感到好奇,可以阅读Scott Wlaschin's series on computation expressions,这很好地解释了这一点。