【PL理论深化】(7) Ocaml 语言:静态类型语言 | 自动类型推断 | 多态类型和多态函数 | let-多态类型系统

news2024/11/19 8:31:07

  • 💬 写在前面:OCaml 是一种拥有静态类型系统的语言,本章我们就要探讨静态类型系统。

目录

0x00 静态类型系统

0x01 自动类型推断(automatic type inference)

0x02 多态类型和多态函数

0x03 let-多态类型系统(let-polymorphic type system)


0x00 静态类型系统(Static Type System

OCaml 是一种拥有 静态类型系统 的语言。一般来说,编程语言可以分为两种:

  1. 拥有静态类型语言(statically typed language)
  2. 拥有动态类型语言(dynamically typed language)

OCaml 与 C, C++, Java, Scala 等语言一样,属于静态类型系统的语言。

这些语言在编译阶段进行静态类型检查,因此带有类型错误的程序无法通过编译器。

# 1 + true;;
Error: This expression has type bool but an
expression was expected of type int

然而,像Python、Lisp这样具有动态类型系统的语言在程序执行过程中执行类型检查。

它们不会预先检查程序中是否存在类型错误,而是在运行时监控类型不匹配的计算发生情况。

.

这两种类型具有相反的优缺点。

具有静态类型系统的语言可在开发过程中检测类型错误,非常适合需要高稳定性的程序开发。

相反具有动态类型系统的语言比静态语言更自由、更灵活。因此程序开发速度更快。

.

具有静态类型系统的语言可以进一步分为两种。

第一种是配备了安全类型系统的语言,

它们能够在编译阶段准确地找到程序执行期间可能发生的所有类型错误:

如 OCaml, Haskell, Scala 等函数式语言通常属于这一类。

第二种是虽然具有静态类型系统,但在运行时仍然可能发生类型错误的不安全语言,如C, C++。

.

OCaml 在静态检查程序类型的同时也能够自动推断类型。

例如,在 C 或 Java 中,必须始终显式地声明变量和函数的类型。

public static int f(int n) {
    int a = 2;
    return a * n;
}

0x01 自动类型推断(automatic type inference)

在 OCaml 中,可以如下定义该函数,而无需类型信息,并且编译器会自动推断类型。

# let f n =
let a = 2 in
a * n;;
val f : int -> int = <fun>

OCaml 可以自动推断类型,即使程序非常复杂也能做到。

为了方便大家了解 OCaml 执行器如何自动推断类型,让我们以前面定义的函数 sum 为例:

# let sum f a b =
(if f a then a else 0) + (if f b then b else 0)
val sum : (int -> bool) -> int -> int -> int = <fun>

OCaml 通过分析函数体来自动推断类型信息。

首先,在条件表达式 if e1 then e2 else e3 中,要求 e_2 和 e_3 的类型必须相同,

并且因为 0 的类型是整数,可以推断出参数 a 和 b 的类型为 int

接下来,函数 `f` 被作为函数调用的形式(如 `f a` 或 `f b`)使用,因此应该具有函数类型。

.

根据 `f` 的参数是 `a` 或 `b`,以及 `f a` 和 `f b` 的结果作为条件表达式 e_1 的一部分使用,

可以推断出 `f` 的类型应该是 `int -> bool`。

最后,由于 `sum` 返回加法结果,可以推断其类型为 `int`。通过这样的过程:

OCaml 的自动类型推断算法能够在执行程序代码之前自动推断出类型,当然也可以手动指定:

# let sum (f : int -> bool) (a : int) (b : int) : int
= (if f a then a else 0) + (if f b then b else 0);;
val sum : (int -> bool) -> int -> int -> int = <fun>

在这种情况下,OCaml 会验证用户是否正确地指定了类型。

例如,如果用户指定的类型是错误的,它会自动找出对应错误。

# let sum (f : int -> int) (a : int) (b : int) : int =
(if f a then a else 0) + (if f b then b else 0);;
Error: The expression (f a) has type int but an
expression was expected of type bool

用户误将函数 f 的类型写成了 int -> int,但实际上 f 的结果类型应该是 bool,这是错误的。

由于 OCaml 的类型系统是安全的,因此如果用户在类型上犯了错,系统一定会指出来。

0x02 多态类型和多态函数

有时候,可能会存在某些情况下无法确定一个表达式的确切类型。

例如,下面定义的函数 id 是一个可以对任意类型使用的函数:

# let id x = x;;
val id : ’a -> ’a = <fun>
# id 1;;
- : int = 1
# id "abc";;
- : string = "abc"
# id true;;
- : bool = true

在这种情况下,使用像 'a 这样的类型变量来表示类型,以便函数可以针对任意类型进行操作。

这种类型称为 多态类型 (polymorphic type),

而拥有多态类型的函数称为 多态函数 (polymorphic function) 。

这意味着这些函数可以适用于任意类型。

0x03 let-多态类型系统(let-polymorphic type system)

OCaml的多态类型系统并不完全自由,只支持通过 `let` 定义的多态函数。

这样的类型系统称为 let-多态类型系统 (let-polymorphic type system) 。

例如,如果像下面这样定义函数 f,它将被识别为多态函数,并且可以在没有问题的情况下执行:

# let f = fun x -> x in
let x = f 1 in
let y = f true in
3;;
- : int = 3

但如果不使用 let 语法,直接按以下方式编写具有相同意义的程序,将会导致类型错误。

# (fun f ->
    let x = f 1 in
        let y = f true in
            3) (fun x -> x);;
Error: The expression has type bool but an expression
was expected of type int

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

📜 参考资料 

- R. Neapolitan, Foundations of Algorithms (5th ed.), Jones & Bartlett, 2015.

- T. Cormen《算法导论》(第三版),麻省理工学院出版社,2009年。

- T. Roughgarden, Algorithms Illuminated, Part 1~3, Soundlikeyourself Publishing, 2018.

- J. Kleinberg&E. Tardos, Algorithm Design, Addison Wesley, 2005.

- R. Sedgewick&K. Wayne,《算法》(第四版),Addison-Wesley,2011

- S. Dasgupta,《算法》,McGraw-Hill教育出版社,2006。

- S. Baase&A. Van Gelder, Computer Algorithms: 设计与分析简介》,Addison Wesley,2000。

- E. Horowitz,《C语言中的数据结构基础》,计算机科学出版社,1993

- S. Skiena, The Algorithm Design Manual (2nd ed.), Springer, 2008.

- A. Aho, J. Hopcroft, and J. Ullman, Design and Analysis of Algorithms, Addison-Wesley, 1974.

- M. Weiss, Data Structure and Algorithm Analysis in C (2nd ed.), Pearson, 1997.

- A. Levitin, Introduction to the Design and Analysis of Algorithms, Addison Wesley, 2003. - A. Aho, J. Hopcroft, and J. Ullman, Data Structures and Algorithms, Addison-Wesley, 1983.

- E. Horowitz, S. Sahni and S. Rajasekaran, Computer Algorithms/C++, Computer Science Press, 1997.

- R. Sedgewick, Algorithms in C: 第1-4部分(第三版),Addison-Wesley,1998

- R. Sedgewick,《C语言中的算法》。第5部分(第3版),Addison-Wesley,2002

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

php,python AES/CBC/PKCS7Padding加密解密 base64/hex编码

1. python版本 import base64 from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpadclass AESUtilCBC:def __init__(self, key, iv):self.key key.encode(utf-8)self.iv iv.encode(utf-8)self.pad_length AES.block_sizedef encrypt(self, data):try…

最佳实践 | HelpLook通过PartnerShare实现低成本的市场拓展

在如今许多行业市场竞争非常激烈&#xff0c;扩大品牌影响力、提升产品竞争力成为企业亟待攻克的难题之一。为此&#xff0c;HelpLook AI知识库对接了PartnerShare联盟系统&#xff0c;为SaaS产品如何做好全民分销带来了全新的解决思路。 PartnerShare凭借成熟的推广体系为Hel…

一张图了解KFS

供稿&#xff1a;产品研发中心、战略市场部 编辑&#xff1a;薇薇 审核&#xff1a;日尧

源站静态文件更新后,CDN会自动刷新吗

源站静态文件更新后&#xff0c;CDN不会自动刷新缓存&#xff0c;而是在缓存时间过期后&#xff0c;才会经由用户触发回源获取最新文件。如希望在缓存过期时间之前&#xff0c;实现CDN节点与源站静态文件同步更新&#xff0c;则需要通过CDN控制台-【刷新预取】菜单&#xff0c;…

前端JS必用工具【js-tool-big-box】学习,数值型数组的正向排序和倒向排序

这一小节&#xff0c;我们说一下前端 js-tool-big-box 这个工具库&#xff0c;添加的数值型数组的正向排序和倒向排序。 以前呢&#xff0c;我们的数组需要排序的时候&#xff0c;都是在项目的utils目录里&#xff0c;写一段公共方法&#xff0c;弄个冒泡排序啦&#xff0c;弄…

量化交易面临的难题

量化交易面临的难题 1、监管机构对于算法交易、量化交易的监管越来越严格3、回测场景于实盘交易场景的不匹配性4、策略并非100%有效&#xff0c;并非100%的收益5、股票、基本面、市场新闻之间的关系时刻在变化并且难以捉摸6、很难使用一套通用的交易规则去匹配所有的股票/市场/…

React Native V0.74 — 稳定版已发布

嗨,React Native开发者们, React Native 世界中令人兴奋的消息是,V0.74刚刚在几天前发布,有超过 1600 次提交。亮点如下: Yoga 3.0New Architecture: Bridgeless by DefaultNew Architecture: Batched onLayout UpdatesYarn 3 for New Projects让我们深入了解每一个新亮点…

OElove 婚恋系统 v10.2升级真是及时,你们是不是UI团队换了?不得不说这次UI是真美!当然功能也升级了大大的赞!

怎么说呢&#xff0c;成为OE的老用户已经有五年了&#xff0c;当时买的初衷就是在本地做一个响当当的门户但是因为疫情搁浅了。。。实在是入不敷出&#xff01;转行的这几年又看好了婚恋这个行业于是打算冲头再来&#xff0c;我记得我当时还是8.5&#xff0c;功能比较强大就是太…

CppTest单元测试框架(更新)

目录 1 背景2 设计3 实现4 使用4.1 主函数4.2 使用方法 1 背景 前面文章单元测试之CppTest测试框架中讲述利用宏ADD_SUITE将测试用例自动增加到测试框架中。但在使用中发现一个问题&#xff0c;就是通过宏ADD_SUITE增加多个测试Suite时&#xff0c;每次运行时都是所有测试Suit…

内附下载方式 | 移远通信《5G RedCap技术发展及应用白皮书》重磅发布

6月25日&#xff0c;在2024 MWC上海前夕&#xff0c;全球领先的物联网整体解决方案供应商移远通信宣布&#xff0c;正式发布其《5G RedCap技术发展及应用白皮书》。 该白皮书对RedCap的技术特点、市场趋势及应用场景进行了全面分析&#xff0c;基于5G技术的发展和演进&#xff…

Kafka入门-基础概念及参数

一、Kafka术语 Kafka属于分布式的消息引擎系统&#xff0c;它的主要功能是提供一套完备的消息发布与订阅解决方案。可以为每个业务、每个应用甚至是每类数据都创建专属的主题。 Kafka的服务器端由被称为Broker的服务进程构成&#xff0c;即一个Kafka集群由多个Broker组成&#…

一款开源、高颜值的AI物联网数据平台

介绍 AIOT人工智能物联网平台是一站式物联网开发基础平台&#xff0c;帮助企业快速实现数字化、精细化数据管理。核心系统为&#xff1a;物联网平台 数据中台&#xff08;数据底座&#xff09; AI。 同时支持文生图、语音合成等。大模型支持陆续也会慢慢开发。 物联系统介绍…

STM32存储左右互搏 模拟U盘桥接QSPI总线FATS读写FLASH W25QXX

STM32存储左右互搏 模拟U盘桥接QSPI总线FATS读写FLASH W25QXX STM32的USB接口可以模拟成为U盘&#xff0c;通过FATS文件系统对连接的存储单元进行U盘方式的读写。 这里介绍STM32CUBEIDE开发平台HAL库模拟U盘桥接Quad SPI总线FATS读写W25Q各型号FLASH的例程。 FLASH是常用的一种…

【学习】科大睿智解读ITSS通过后仍需关注和改进IT服务的原因

为了确保IT服务的质量和效率&#xff0c;很多企业拿到ITSS资质证书后&#xff0c;仍然需要持续关注和改进IT服务&#xff0c;科大睿智总结主要原因有以下几点&#xff1a; 1、随着企业发展业务和市场行情的变化&#xff0c;可能涉及到运维服务中新的业务流程、技术需求或者用户…

[深度学习] 门控循环单元GRU

门控循环单元&#xff08;Gated Recurrent Unit, GRU&#xff09;是一种用于处理序列数据的递归神经网络&#xff08;Recurrent Neural Network, RNN&#xff09;变体&#xff0c;它通过引入门控机制来解决传统RNN在处理长序列时的梯度消失问题。GRU与长短期记忆网络&#xff0…

Arduino 旋转编码器

Arduino 旋转编码器 电位计 Arduino - Rotary Encoder In this tutorial, we are going to learn how to use the incremental encoder with Arduino. In detail, we will learn: 在本教程中&#xff0c;我们将学习如何将增量编码器与Arduino一起使用。详细来说&#xff0c;…

iptables(11)target(SNAT、DNAT、MASQUERADE、REDIRECT)

简介 前面我们已经介绍了ACCEPT、DROP、REJECT、LOG,这篇文章我们介绍SNAT、DNAT、MASQUERADE、REDIRECT,这几个参数的定义我们在上篇文章中都有介绍,我这里再列出回顾一下 DNAT(目标地址转换)和 SNAT(源地址转换) 原理:修改数据包的源或目标 IP 地址。通常用于 NAT(…

Maven高级理解属性

属性 在这一章节内容中&#xff0c;我们将学习两个内容&#xff0c;分别是 属性版本管理 属性中会继续解决分模块开发项目存在的问题&#xff0c;版本管理主要是认识下当前主流的版本定义方式。 4.1 属性 4.1.1 问题分析 讲解内容之前&#xff0c;我们还是先来分析问题: …

Games101 透视投影矩阵推导

目录 齐次坐标 透视投影 透视投影的四棱锥体挤压为正交投影的长方体 变换规定 转换过程 观察1 观察2 关于任意一点挤压后向哪里移动的问题&#xff0c;简单推导了一下 齐次坐标 如下&#xff0c;(x, y, z, 1) 表示空间中的xyz点&#xff0c;让它每个分量乘以k&#…

MySQL 基础概念

MySQL逻辑架构 MySQL 服务器逻辑架构图 最上层的服务并不是MySQL所独有的&#xff0c;大多数基于网络的客户端/服务器的工具或者服务都有类似的架构&#xff0c;比如连接管理、授权认证、安全等等。 大多数MySQL的核心服务都在第二层&#xff0c;包括查询解析、分析、优化、…