【PL理论】(12) F#:模块 | 命名空间 | 异常处理 | 内置异常 |:? | 相互递归函数

 

  • 💭 写在前面:本章我们将介绍 F# 的模块,我们前几章讲的列表、集合和映射都是模块。然后我们将介绍 F# 中的异常,以及内置异常,最后再讲解一下相互递归函数。

目录

0x00 F# 模块(Module)

0x01 F# 异常处理(Exception)

0x02 内置异常(Built-in Exceptions)

0x03 相互递归函数

0x04 通过泰勒级数展开来逼近计算 e^x


0x00 F# 模块(Module)

用于代码组织和抽象的特性,模块 (Module) 就是相关类型、值和函数的集合。

类似于面向对象编程中的类,但没有对象的概念。

比如我们说的的列表、集合和映射都是模块。

在这个章节后,我会给出一点练习题,方便大家更好地掌握 F# 基础。

为了方便大家没有负担地有效练习,我会在框架代码中勾勒出模块,你只需要填写就行了:

namespace DataStructure

module Queue =
  type t = int list * int list
  let empty: t = ([], [])
  let enqueue (i: int) (queue: t) = ...

另外,这个 namespace 就是命名空间,类似于 C++。

0x01 F# 异常处理(Exception)

F# 中也是可以 raise 捕获异常的,raise ... 会被求值为一个异常并传播。

使用 try-with 来捕获引发的异常,异常会被视为 any type,可以是任何类型 ( `a ) 。 

exception DivByZero

let div (x: int) (y: int) : int =
  if y = 0 then raise DivByZero else x / y

let printDiv (x: int) (y: int) : unit =
  try printfn "%d" (div x y) with
  | DivByZero -> printfn "Divisor is zero" 

0x02 内置异常(Built-in Exceptions)

F# 有不少预定义的异常,要捕获这些错误,你必须使用 |:? 

这是因为 F# 与 C# (.NET) 都是一个爹有着密不可分的关系。

这里提供几种还不错的选择,让你避免记住这些复杂的异常名称:

let doFind1 (k: string) (m: Map<string,int>) : int =
  try Map.find k m with
  | :? System.Collections.Generic.KeyNotFoundException -> 0

let doFind2 (k: string) (m: Map<string,int>) : int =
  if Map.containsKey k m then Map.find k m else 0

let doFind3 (k: string) (m: Map<string,int>) : int =
  match Map.tryFind k m with
  | None -> 0 | Some i -> i

0x03 相互递归函数

相互递归函数 (Mutually Recursive Function),指的是多个函数可以相互递归调用。

简单来说就是你递归调用我,我递归调用你,用 let rec ... and 语法来定义这样的函数。

💬 举个例子:我们来定义三个相互递归的函数

let rec f x =
  x + g (x - 1)

and g y =
  if y <= 1 then 1 else y * h (y - 1)

and h z =
  if z <= 2 then 0 else f (z - 1) + f (z - 2)

这段代码定义了三个相互递归的函数 f,g,h,它们彼此之间互相调用。

形成了一个循环,每个函数的返回值都依赖于其他函数的返回值,从而实现了相互递归。

0x04 通过泰勒级数展开来逼近计算 e^x

通过泰勒级数展开来逼近计算 e^x

① 首先计算 n 的阶乘:

n!=n\times (n-1)\times(n-2)\times...\times2\times1

我们定义一个递归函数 Fac 计算一个非负整数的阶乘,当输入值 n\leq 1 时,返回1。

否则,返回 n 乘以 (n-1)  的阶乘。

在 Tylor 函数中,Fac 被用来计算泰勒级数展开的分母部分,即 n!  。

② 再通过泰勒级数展开公式 (以 e 为底的指数函数) ,我们展开前十项:

e^x=\sum_{n=0 }^{\infty }\frac{x^n}{n!}\, \, \, \Rightarrow \, \, \, e^x\approx \sum_{n=0 }^{10}\frac{x^n}{n!}

再定义一个递归函数 Taylor 计算 e^x 的泰勒级数展开,当展开的级数项数 n=0 时,返回 1.0

否则计算 x^n/n!  并加上递归调用 Taylor 函数计算更低阶的项。

在 Taylor 函数中,Fac 函数被用来计算每一项的阶乘。

💬 代码演示:通过泰勒级数展开来逼近计算 e^x

let rec Fac n =
    if n <= 1 then 1
    else n * Fac (n - 1)

let rec Taylor x n =
    if n = 0 then 1.0
    else (float x ** float n) / float (Fac n) + Taylor x (n - 1)

// 计算 e^x 的值
let calculateExponential x =
    if System.Double.IsNaN(x) || System.Double.IsInfinity(x) then
        invalidArg "x" "x must be a finite number"
    else
        Taylor x 10  // 前10项

这两个函数就相互递归了,因为 Taylor 调用了 Fac 来计算阶乘,而 Fac 也会调用 Taylor。

你可以发现,我们没有使用刚才讲的 "0x03 相互递归",let rec ... and。

因为每次计算阶乘都会重新计算泰勒级数的一部分,导致大量的重复计算:

let rec Fac n =
    if n <= 1 then 1
    else n * Taylor (n - 1) 1

and Taylor x n =
    if n = 0 then 1.0
    else (float x ** float n) / float (Fac n) + Taylor x (n - 1)

// 计算 e^x 的值
let calculateExponential x =
    if System.Double.IsNaN(x) || System.Double.IsInfinity(x) then
        invalidArg "x" "x must be a finite number"
    else
        Taylor x 10  // 前10项

// 测试计算函数
let result = calculateExponential 1.0
printfn "e^1 的值近似为: %f" result


📌 [ 笔者 ]   王亦优
📃 [ 更新 ]   2024.6.16
❌ [ 勘误 ]   /* 暂无 */
📜 [ 声明 ]   由于作者水平有限,本文有错误和不准确之处在所难免,
              本人也很想知道这些错误,恳望读者批评指正!

📜 参考资料 

Microsoft. MSDN(Microsoft Developer Network)[EB/OL]. []. .

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/694114.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

堡垒机的自动化运维,快速安全提升运维效率

随着信息技术的突飞猛进&#xff0c;企业对于IT系统的依赖程度日益加深&#xff0c;不仅希望可以提高运维效率&#xff0c;也希望能保障IT系统的安全。因此堡垒机与自动化运维技术的结合应运而生&#xff0c;堡垒机的自动化运维&#xff0c;快速安全提升运维效率。今天我们就来…

人工智能和物联网如何结合

欢迎来到 Papicatch的博客 文章目录 &#x1f349;引言 &#x1f349;AI与IoT的结合方式 &#x1f348;数据处理和分析 &#x1f34d;实例 &#x1f348;边缘计算 &#x1f34d;实例 &#x1f348;自动化和自主操作 &#x1f34d;实例 &#x1f348;安全和隐私保护 &…

YOLOv10 超详细解析 | 网络结构、训练策略、论文解读

网络结构 1. Backbone 2. Head 3. 说明 网络结构按 YOLOv10m 绘制&#xff0c;不同 scale 的模型在结构上略有不同&#xff0c;而不是像 YOLOv8 一样仅调整 depth 和 width。Head 有部分后续计算与 YOLOv8 完全相同&#xff0c;上图省略&#xff0c;具体请看此文。YOLOv10 整…

以sqlilabs靶场为例,讲解SQL注入攻击原理【42-53关】

【Less-42】 使用 or 11 -- aaa 密码&#xff0c;登陆成功。 找到注入点&#xff1a;密码输入框。 解题步骤&#xff1a; # 获取数据库名 and updatexml(1,concat(0x7e,(select database()),0x7e),1) -- aaa# 获取数据表名 and updatexml(1,concat(0x7e,(select group_conca…

QT案例 记录解决在管理员权限下QFrame控件获取拖拽到控件上的文件路径

参考知乎问答 Qt管理员权限如何支持拖放操作&#xff1f; 的回答和代码示例。 解决在管理员权限运行下&#xff0c;通过窗体的QFrame子控件获取到拖拽的内容。 目录标题 导读解决方案详解示例详细 【管理员权限】在QFrame控件中获取拖拽内容 【管理员权限】继承 IDropTarget 类…

Invalid JSON text:“Invalid value.“ at position 0 in value for column ‘user.info

你们好&#xff0c;我是金金金。 场景 我正在练习mybatis-plus&#xff0c;在插入一条数据的时候报错了&#xff0c;错误信息如上图 排查 排查之前我先贴一下代码 以下为数据库字段类型 在插入的过程中报错&#xff1a;Data truncation: Invalid JSON text: "Invalid val…

百度高级项目经理洪刘生受邀为第十三届中国PMO大会演讲嘉宾

全国PMO专业人士年度盛会 百度在线网络技术&#xff08;北京&#xff09;有限公司IDG智能驾驶业务部高级项目经理洪刘生先生受邀为PMO评论主办的2024第十三届中国PMO大会演讲嘉宾&#xff0c;演讲议题为“互联网PMO赋能战略项目集管理实战分享”。大会将于6月29-30日在北京举办…

FCN-语义分割中的全卷积网络

FCN-语义分割中的全卷积网络 语义分割 语义分割是计算机视觉中的关键任务之一&#xff0c;现实中&#xff0c;越来越多的应用场景需要从影像中推理出相关的知识或语义&#xff08;即由具体到抽象的过程&#xff09;。作为计算机视觉的核心问题&#xff0c;语义分割对于场景理…

【西瓜书】9.聚类

聚类任务是无监督学习的一种用于分类等其他任务的前驱过程&#xff0c;作为数据清洗&#xff0c;基于聚类结果训练分类模型 1.聚类性能度量&#xff08;有效性指标&#xff09; 分类任务的性能度量有错误率、精度、准确率P、召回率R、F1度量(P-R的调和平均)、TPR、FPR、AUC回归…

流程的控制

条件选择语句 我们一般将条件选择语句分为三类&#xff1a; 单条件双条件多条件 本篇文章将分开诉说着三类。 单条件 单条件的语法很简单&#xff1a; if (条件) {// 代码}条件这里我们需要注意下&#xff0c;可以向里写入两种&#xff1a; 布尔值布尔表达式 当然&…

【算法刷题 | 动态规划08】6.9(单词拆分、打家劫舍、打家劫舍||)

文章目录 21.单词拆分21.1题目21.2解法&#xff1a;动规21.2.1动规思路21.2.2代码实现 22.打家劫舍22.1题目22.2解法&#xff1a;动规22.2.1动规思路22.2.2代码实现 23.打家劫舍||23.1题目23.2解法&#xff1a;动规23.2.1动规思路23.2.2代码实现 21.单词拆分 21.1题目 给你一…

Unity动画录制工具在运行时录制和保存模型骨骼运动的方法录制动画给其他角色模型使用支持JSON、FBX等格式

如果您正在寻找一种在运行时录制和保存模型骨骼运动的方法&#xff0c;那么此插件是满足您需求的完美解决方案。 实时录制角色运动 将录制到的角色动作转为动画文件 将录制好的动作给新的角色模型使用&#xff0c;完美复制 支持导出FBX格式 操作简单&#xff0c;有按钮界面…

Nacos的配置中心

1.前言 除了注册中心和负载均衡之外, Nacos还是⼀个配置中心, 具备配置管理的功能. Namespace 的常用场景之一是不同环境的配置区分隔离&#xff0c; 例如开发测试环境和⽣产环境的配置隔离。 1.1 为什么需要配置中心&#xff1f; 当前项目的配置都在代码中&#xff0c;会存…

网络基础-IP协议

文章目录 前言一、IP报文二、IP报文分片重组IP分片IP分片示例MTUping 命令可以验证MTU大小Windows系统&#xff1a;Linux系统: 前言 基础不牢&#xff0c;地动山摇&#xff0c;本节我们详细介绍IP协议的内容。 一、IP报文 第一行&#xff1a; 4位版本号指定IP协议的版本&#…

原来你长这个样子啊,Java字节码文件

字节码文件 字节码文件是一种二进制文件&#xff0c;扩展名为.class 通过 javac 将源码编译得到&#xff0c;是一种中间形式的代码&#xff0c;这种中间形式的代码让Java有了“一次编译&#xff0c;多次运行”的跨平台特点。 字节码文件的组成 由5大组成部分&#xff1a;基础…

9.3 Go 接口的多态性

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

Python第二语言(六、Python异常)

目录 1. 捕获异常&#xff08;try: except: else: finally:&#xff09; 1.1 概念 1.2 基础语法&#xff08;try&#xff1a; except&#xff1a;&#xff09; 1.3 捕获异常&#xff08;异常也有类型&#xff09; 1.4 捕获多个异常&#xff08;try&#xff1a;except(Name…

UI学习的案例——照片墙

照片墙案例 在实现照片墙案例之前先讲一下userInteractionEnable这个属性。 首先这个属性属于UIView&#xff0c;这个属性是bool类型&#xff0c;如果为YES的话&#xff0c;这个UIView会接受有关touch和keyboard的相关操作&#xff0c;然后UIView就可以通过相应的一些方法来处…

C语言详解(联合和枚举)

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;所属专栏&#xff1a;C语言 &#x1f680;本系列文章为个人学习笔记&#xff0c;在这里撰写…

多粒度特征融合(细粒度图像分类)

多粒度特征融合&#xff08;细粒度图像分类&#xff09; 摘要Abstract1. 多粒度特征融合1.1 文献摘要1.2 研究背景1.3 创新点1.4 模型方法1.4.1 Swin-Transformer1.4.2 多粒度特征融合模块1.4.3 自注意力1.4.4 通道注意力1.4.5 图卷积网络1.4.6 基于Vision-Transformer的两阶段…