当前位置:  开发笔记 > 编程语言 > 正文

如何在'let'定义中使用模式匹配?

如何解决《如何在'let'定义中使用模式匹配?》经验,为你挑选了3个好方法。

我刚刚注意到F#允许我使用带有文字和其他模式的let绑定,如下所示:

let fib 0 = 1
let exists item [] = false
let car (hd :: tl) = hd
let cdr (hd :: tl) = tl

F#正确地将这些函数解释为一种模式匹配,因为我给出了以下警告:

警告1此表达式的不完整模式匹配.例如,值"1"将不匹配

警告2此表达式的不完整模式匹配.例如,值"[_]"将不匹配

等等

这些函数按预期工作,但我想用这种样式定义一个具有完全模式匹配的函数,但是我在F#手册中找不到关于这种替代模式匹配语法的任何信息.

我知道我可以使用let whatever = function ...let whatever x = match x with ...获得我想要的结果,但我刚刚发现了另一种模式匹配的语法,如果我不知道如何使用它,它会永远唠叨我.

如何使用上面显示的替代模式匹配语法编写函数?



1> JaredPar..:

AFAIK,F#中没有办法声明具有相同名称和不同模式匹配签名的多个let绑定.我相信与你正在寻找的最接近的构造是一个函数规则表达式.

以这个例子为汽车

let car = function
    | hd::tl -> hd
    | [] -> failwith "empty list"



2> Brian..:

JaredPar是对的,F#没有Haskell在这里做的句法形式.

F#表单主要用于打开单个案例区分联合或用于定义不完整匹配的函数(例如在空列表中失败的'car'示例).这只是一个事实的结果,实际上语言中的所有名称绑定都是通过模式完成的; 由于您所描述的确切原因,这种句法形式(使用参数上的模式定义函数)在实践中通常不太有用.

我认为Haskell在语法形式方面做了很多比ML更好的事情,但F#的根源是ML.好处是有一个很好的F#子集与OCaml交叉编译(它帮助引导了F#语言和用户社区); 缺点是F#被一些丑陋/有限的语法"卡住"了.



3> bytebuster..:

显然,F#的模式匹配比我们在共同开发中使用的方式更强大.

首先,您可以一次绑定多个值.通常情况下,您将使用List.partition:

let data = [7;0;0;0;1;0;1;1;1;1;0;0;1;1;0]
let ones, others = data |> List.partition ((=) 1) // bind two values

作为旁注,您可以将多个标识符绑定到相同的值:

let (a & b) = 42 // a = 42; b = 42

让我们从简单的let绑定开始,为了简单起见.

let hd::tl = data

警告FS0025:此表达式上的不完整模式匹配.例如,值"[]"可以指示模式未涵盖的情况.

为了缓解这种情况,我们必须为空列表添加另一个案例:

let (hd::tl) | [] = data

错误FS0018:此"或"模式的两边绑定不同的变量集

这是真的; 如果是空列表,hdtl保持未绑定状态.tl使用相同的空列表绑定很容易:

let (hd::tl) | ([] as tl) = data

但是,错误错误FS0018不会消失.实际上,我们还必须提供一些"默认"值hd.
以下脏技巧会做到这一点.

let (hd::tl, _) | ([] as tl , hd) = data, 42

如果列表不为空,或者在第二个值中提供额外值,则上面的行将绑定hddata头部.tuple

注意:我还没有发现嵌入的方式42进入let结构.

最后,car功能相同:

let car ((hd::tl, _) | ([] as tl, hd)) = hd
let foo = car(data, 42) // foo = 7
let bar = car([], 42)   // bar = 42

推荐阅读
手机用户2502851955
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有