F# 中使用守卫与 if/else 结构进行模式匹配

2023-11-26

在 ML 系列语言中,人们倾向于更喜欢模式匹配if/else构造。在 F# 中,在模式匹配中使用防护可以轻松替换if/else在很多情况下。

例如,一个简单的delete1可以在不使用的情况下重写函数if/else (see delete2):

let rec delete1 (a, xs) =
    match xs with
    | [] -> []
    | x::xs' -> if x = a then xs' else x::delete1(a, xs') 

let rec delete2 (a, xs) =
    match xs with
    | [] -> []
    | x::xs' when x = a -> xs'
    | x::xs' -> x::delete2(a, xs') 

另一个例子是求解二次函数:

type Solution =
    | NoRoot
    | OneRoot of float
    | TwoRoots of float * float

let solve1 (a,b,c) = 
    let delta = b*b-4.0*a*c
    if delta < 0.0 || a = 0.0 then NoRoot 
    elif delta = 0.0 then OneRoot (-b/(2.0*a))
    else 
        TwoRoots ((-b + sqrt(delta))/(2.0*a), (-b - sqrt(delta))/(2.0*a))

let solve2 (a,b,c) = 
    match a, b*b-4.0*a*c with
    | 0.0, _  -> NoRoot
    | _, delta when delta < 0.0 -> NoRoot
    | _, 0.0 -> OneRoot (-b/(2.0*a))
    | _, delta -> TwoRoots((-b + sqrt(delta))/(2.0*a),(-b - sqrt(delta))/(2.0*a))

我们是否应该使用与守卫的模式匹配来忽略丑陋if/else构造?

使用模式匹配与防护是否会对性能产生影响?我的印象是,它似乎很慢,因为模式匹配是在运行时检查的。


正确答案可能是这取决于,但我推测,在大多数情况下,编译后的表示是相同的。举个例子

let f b =
  match b with
  | true -> 1
  | false -> 0

and

let f b =
  if b then 1
  else 0

两者都翻译为

public static int f(bool b)
{
    if (!b)
    {
        return 0;
    }
    return 1;
}

鉴于此,这主要是风格问题。就我个人而言,我更喜欢模式匹配,因为大小写总是对齐​​的,使其更具可读性。此外,它们(可以说)更容易在以后扩展以处理更多情况。我认为模式匹配是一种演变if/then/else.

无论有或没有防护,模式匹配都不会产生额外的运行时成本。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

F# 中使用守卫与 if/else 结构进行模式匹配 的相关文章

  • 专家 f# 脚本编译奇怪

    第 209 210 页有一个扩展示例 见下文 我使用的是 F 4 5 总之 我不明白的是 如果我单独键入每个语句 则会有一个声明引发错误 如果我立即提交整个脚本 以及引发错误的声明之后的函数 则一切正常 那么 当我批量提交所有语句时 交互中
  • 您将如何在 F# 中解决这个问题? (高频传感器数据)

    我是一名机械工程研究生 我的导师刚刚要求我为我们的一个传感器项目编写一个数据可视化实用程序 由于现在是夏天 他希望我能从中获得一些乐趣 我认为这将是学习一门擅长科学计算的语言的好时机 所以我直接开始学习 F 由于我是函数式编程范例的新手 因
  • F#:模式构成?

    我正在尝试编写一个由另外两个模式组成的模式 但我不确定如何去做 我的输入是字符串列表 文档 我有一个与文档标题匹配的模式和一个与文档正文匹配的模式 该模式应该匹配整个文档并返回标题和正文模式的结果 您可以使用以下命令一起运行两个模式 您在问
  • F# 中的递归对象?

    这段 F 代码 let rec reformat new EventHandler fun gt b TextChanged RemoveHandler reformat b gt ScrollParser rewrite contents
  • 使用列表匹配绑定值(没有编译器警告)

    假设我有一个需要一些时间的函数int参数 但在其中我将使用float32 我不想使用float32 i无处不在的功能 相反 我想这样做 let x float32 x let y float32 y let w float32 w let
  • OpenCV 完美识别物体

    我有一个应用程序 我想一次跟踪 2 个在图片中相当小的对象 该应用程序应该在 Android 和 iPhone 上运行 因此算法应该是高效的 对于我的客户来说 如果我们提供一些模式以及附加到要跟踪的对象的软件 以获得易于识别的目标 那就完全
  • 如何向 Scotty 中间件添加基本身份验证?

    我目前正在制作 Scotty API 但找不到任何 basicAuth 实现的示例 Wai Middleware HttpAuth 具体来说 我想将基本身份验证标头 用户 通行证 添加到我的某些端点 即以 admin 开头的端点 我已经设置
  • 在构建服务器上安装 F# 4.1 SDK

    我已在 PC 上安装了支持 F 的 Visual Studio 2017 并且 MSBuild 目标位于C Program Files x86 Microsoft Visual Studio 2017 Enterprise MSBuild
  • 什么是 ref 可以做但引用却不能做的事情?

    什么可以ref难道参考文献不能吗 可以 match value try thing Some ref e gt do stuff e 不能同等地表达为 match value try thing Some e gt do stuff e 编
  • 如何在不进行尾调用优化的情况下用函数式编程替代方案替换 while 循环?

    我正在 JavaScript 中尝试一种更实用的风格 因此 我用诸如map和reduce之类的实用函数替换了for循环 然而 我还没有找到 while 循环的功能替代品 因为尾部调用优化通常不适用于 JavaScript 据我了解 ES6
  • 使用部分函数短路列表映射

    因此 我创建了一个名为 tryMap 的函数 如下所示 tryMap with failure and success continuations let rec tryMapC R gt U list gt R gt T gt U opt
  • 如何在 F# 中实现返回 void 的接口成员

    想象一下 C 中的以下接口 interface IFoo void Bar 我如何在 F 中实现这一点 我在 30 分钟的在线搜索中找到的所有示例都仅显示具有返回类型的示例 我认为这在函数式风格中更常见 但在这种情况下我无法避免 这是我到目
  • F#:仅对第一个事件执行一次操作,没有可变性/锁定?

    我有这段代码 可以下载文件并在控制台中告诉我该文件有多大 use webClient new WebClient let lockObj new Object let mutable firstProgressEvent true let
  • F# 之于 IronPython/IronRuby 就像 C# 之于 VB.NET 一样?

    我刚刚听了Chris Smith 谈论 F 的播客 http www code magazine com codecast index aspx messageid 7feb501f 25c8 432a 9624 97082f1e75e8他
  • 您能给我解释一下 OCaml 函子吗? [复制]

    这个问题在这里已经有答案了 可能的重复 在函数式编程中 什么是函子 https stackoverflow com questions 2030863 in functional programming what is a functor
  • Swift:配对数组元素的最佳方法是什么

    我遇到了一个需要成对迭代数组的问题 最好的方法是什么 或者 作为替代方案 将数组转换为对数组 然后可以正常迭代 的最佳方法是什么 这是我得到的最好的 这个需要output成为一个var 而且它并不是很漂亮 有没有更好的办法 let inpu
  • 设计 React Hooks 可防止 React-hooks/exhaustive-deps 警告

    我正在设计一个钩子 仅当钩子依赖项发生变化时才获取数据 它按预期工作但我收到了 linter 警告 React Hook useEffect was passed a dependency list that is not an array
  • 生成 .tail IL 指令的简单 F# 代码是什么?

    我想看看 tailIL 指令 但我一直在编写的使用尾部调用的简单递归函数显然已优化为循环 我实际上是在猜测这一点 因为我不完全确定反射器中的循环是什么样的 我绝对没有看到任何 tail不过操作码 我在项目的属性中检查了 生成尾部调用 我还尝
  • Haskell 中的所有图形和 Web 库是如何实现的?

    我才开始学习Haskell 我读到它是一种纯函数式语言 其中的所有内容都是不可变的 因此 输入输出 写入和读取数据库之类的事情会导致状态的可变性 我知道 Haskell 中有一种叫做 monad 的东西 它允许在 Haskell 中使用命令
  • 在 Vavr 中结合任一者?

    我有几个Vavr https www vavr io Either https www vavr io vavr docs either的 我想调用一个函数Right每个 Either 的值 例如 Either

随机推荐

  • 使用 Nhibernate 过滤通过聚合根返回的子集合

    我正在尝试在使用 Nhibernate 加载聚合根时过滤它的子集合 向客户加载所有已发货的订单 这可能吗 那么 您可以公开在地图中过滤的属性 如下所示
  • 如何在 processStartInfo 中传递多个参数?

    我想运行一些cmd命令来自c 代码 我关注了一些博客和教程并得到了答案 但我有点困惑 即我应该如何传递多个参数 我使用以下代码 System Diagnostics Process process new System Diagnostic
  • Python美汤表单输入解析

    我的目标是获取所有输入名称和值的列表 将它们配对并提交表格 名称和值是随机的 from bs4 import BeautifulSoup parsing html
  • 可以设置Python对象的任何属性[重复]

    这个问题在这里已经有答案了 例如 这段代码是Python a object a b 3 throws AttributeError object object has no attribute b 但是 这段代码 class c objec
  • 将 sonar.test.exclusions 与 Sonarqube 6.3 一起使用

    我目前正在评估 Sonarqube 6 3 对我当前的 5 5 实例进行了重大升级 并且在尝试找出该功能的过程中我感到很困惑声纳 测试 排除环境 有这样一个问题 Sonar Maven 插件 如何排除测试源目录 这似乎表明它用于从分析中排除
  • Python 中的重复数据删除

    在浏览 Python 中用于重复数据删除的 Dedupe 库的示例时 我发现它创建了一个集群 ID输出文件中的列 根据文档 该列指示哪些记录相互引用 虽然我无法找出两者之间的任何关系集群 ID这对查找重复记录有什么帮助 如果有人对此有见解
  • Java线程阻塞

    我的java环境有问题 我运行 Solr 1 3 搜索引擎 已有一年多了 突然间我遇到了很多麻烦 我所有的线程池 250 每天都会被随机阻塞一两次 我没有对 solr 应用程序或 tomcat 服务器进行任何更改 我正在运行 tomcat
  • 测试两个 __m128i 变量之间的相等性

    如果我想在两个之间进行按位相等测试 m128i变量 我是否需要使用 SSE 指令或者我可以使用 如果不是 我应该使用哪条SSE指令 虽然使用 mm movemask epi8是一种解决方案 如果您有一个带有 SSE4 1 的处理器 我认为更
  • 获取点击事件中按钮的 ID/名称。网络

    我在 VB NET 中有一个事件可以同时处理多个按钮单击 我需要知道选择的哪个按钮启动了事件 有什么想法如何做到这一点 我的代码如下 Private Sub Answer Click ByVal sender As System Objec
  • 检查字符串中是否包含表情符号

    我用这个得到字符串的文本大小 textSize tempDict valueForKeyPath caption text sizeWithFont UIFont systemFontOfSize 12 constrainedToSize
  • 在 C 套接字编程中刷新套接字流

    我想知道如何在用 C 进行套接字编程时刷新套接字流 我尝试了所有选项设置TCP NODELAY使用以下代码 setsockopt sockfd IPPROTO TCP TCP NODELAY char flag sizeof int 注 所
  • 当窗体具有许多下拉列表控件时,C#.net windows 窗体调整大小的速度缓慢

    我制作了一个带有许多下拉列表的 Windows 窗体 这些下拉列表放置在网格 不是数据网格 内 当我在所有这些窗体中使用anchor left right top Bottom 和 dock fill 选项时 窗体调整大小在运行时会变慢 停
  • 使用 Python 从非结构化文本中提取人的年龄

    我有一个行政档案数据集 其中包括简短的传记 我正在尝试使用 python 和一些模式匹配来提取人们的年龄 一些句子的例子是 邦德先生 67 岁 是英国的一名工程师 阿曼达 B 拜恩斯 Amanda B Bynes 34 岁 是一名演员 彼得
  • 如果所有汇总值均为 NA,则 dplyr 汇总保留 NA

    我想使用 dplyr summarize 按组对计数进行求和 具体来说 如果并非所有求和值都是 NA 我想删除 NA 值 但如果所有求和值都是 NA 我想显示 NA 例如 name lt c jack jack mary mary elle
  • PL/SQL FOR 循环隐式游标

    有2张桌子EMPLOYEES and DEPARTMENTS with department id作为主键DEPARTMENTS和外键EMPLOYEES 我想打印属于特定部门的所有员工姓名 我知道它可以通过 JOINS 或 JOINS 轻松
  • 为什么在 Windows 终端中用 Python 进行彩色打印不起作用? [复制]

    这个问题在这里已经有答案了 我可以在 ipython 中以绿色打印 test1 并以红色打印 test2 print 033 92m test1 print 033 91m test2 但在终端中以白色打印出以下错误 92mtest1 91
  • 如何确定我的 python shell 是在 32 位还是 64 位中执行?

    如何从 shell 内部判断 shell 处于什么模式 我试过看platform模块 但它似乎只是告诉您 用于可执行文件的位体系结构和链接格式 我的二进制文件被编译为 64 位 我在 OS X 10 6 上运行 因此即使我使用这些方法 它似
  • 无法加入字符串类型的 pandas 数据框

    我有两个 DataFrames 对象 其列如下 数据框1 df dtypes Output ImageID object Source object LabelName object Confidence int64 dtype objec
  • 从 C# 代码从 SQLite 导入/导出 CSV

    我正在尝试找出一种使用 System Data SQLite 将 CSV 文件加载到 SQLite DB 的简单方法 我看到了命令行方式来做到这一点 即 Import mydata csv mytable 但我需要通过 C 代码来完成此操作
  • F# 中使用守卫与 if/else 结构进行模式匹配

    在 ML 系列语言中 人们倾向于更喜欢模式匹配if else构造 在 F 中 在模式匹配中使用防护可以轻松替换if else在很多情况下 例如 一个简单的delete1可以在不使用的情况下重写函数if else see delete2 le