类型变量和局部抽象类型有什么区别?

2024-04-06

我试图理解的目的局部抽象类型在 OCaml 中。局部抽象类型与类型变量有何不同?看来他们有相同的行为:

(* Type variable *)
# let f (x : 'a) : 'a = x;;
val f : 'a -> 'a = <fun>

(* Locally abstract type *)
# let f (type a) (x : a) : a = x;;
val f : 'a -> 'a = <fun>

统一类型变量和局部抽象类型具有完全不同的行为。

特别是,记住统一类型变量很有用:

  • 可以统一, 例如
let f (x:'a) (y:'a) : 'a = ()

是有效的并且产生f: unit -> unit -> unit.

  • 都在整个顶级定义的范围内。

    例如,变量'a在整个范围内都是相同的f(因此具有类型unit -> unit)

let f x =
   let () = (():'a) in
   (x:'a)

相反,局部抽象类型是:

  • 局部抽象,因此它们不能与任何其他类型统一。

    例如,

let f (type a) (x:a) (y:a) : a = ()

产生预期的

Error: This expression has type unit but an expression was expected of type a
  • 由于范围良好,本地类型的寿命不能超出其范围。 通常,
let f x =
   let y (type a): a = assert false
   (* let's pretend that we can define such `y` value *) in
   (x:a)

产生预期的超出范围的错误

Error: Unbound type constructor a

由于这些根本的行为差异,本地抽象类型已被扩展以支持类型系统的更高级功能。 事实上,局部抽象类型:

  • 可用于定义本地模块,因为它们是类型构造函数而不是类型变量
let f (type a) (cmp:a -> a -> int) (x:a list) =
  let module S = Set.Make(struct type t = a let compare = cmp end) in
  x |> S.of_list |> S.elements
  • 在 GADT 上进行模式匹配时,可以使用局部类型方程进行细化,因为它们具有明确定义的范围:
type _ t =
| Int: int t
| Float: float t
let zero (type a) (x:a t) = match x with
| Int -> 0 (* in this branch a = int *)
| Float -> 0. (* whereas a = float in this one*)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

类型变量和局部抽象类型有什么区别? 的相关文章

  • 使用 OCaml 收集外部命令的输出

    在 OCaml 中调用外部命令并收集其输出的正确方法是什么 在Python中 我可以做这样的事情 os popen cmd read 如何在 OCaml 中获取外部程序的所有输出 或者 更好的是 带有 Lwt 的 OCaml Thanks
  • IsPrimitive 不包含可为 null 的原始值

    我想检查类型是否是原始类型并使用以下代码 return type IsValueType type IsPrimitive 只要原始 int 可为空 这就可以正常工作 例如 int 如何检查该类型是否为可为空的原始类型 供参考 type I
  • 是否可以在 C++ 中创建一种占用少于一个字节内存的类型?

    对于我的计算 我只需要使用 7 位空间 因此我使用 char 类型 但是我想知道是否可以声明我自己的类型 使用少于一字节的内存 并不真地 在结构体内部 您可以使用位字段 http en wikipedia org wiki Bit fiel
  • 是否可以使函数接受给定参数的多种数据类型?

    编写函数时 我必须声明输入和输出数据类型 如下所示 int my function int argument 是否可以声明我的函数接受 int bool 或 char 类型的变量 并且可以输出这些数据类型 non working examp
  • Haskell 重叠/不连贯的实例

    我知道这段代码有点傻 但有人可以解释为什么吗isList 42 回报True然而isList2 42 prints False 以及如何防止这种情况发生 我想更好地理解一些更晦涩的 GHC 类型扩展 我认为这将是一个有趣的例子 LANGUA
  • 什么时候适合使用关联类型而不是泛型类型?

    In 这个问题 https stackoverflow com q 32053402 155423 出现了一个问题 可以通过将使用泛型类型参数的尝试更改为关联类型来解决 这引发了一个问题 为什么关联类型在这里更合适 这让我想了解更多 The
  • Excel VBA 中的 TypeName 返回什么?

    我想检查一下数据类型 Cells 2 1 Value即 这里有什么 以下 我尝试了名称 整数 长整型等 但似乎不接受 If TypeName Cells r 1 Value WHAT GOES HERE Then MsgBox Yes El
  • 如何缩进现有 OCaml 代码

    我有大约 30 000 行缩进严重的 OCaml 代码 包括 mly 和 mll 文件 并且想要缩进它们 我尝试在谷歌上搜索 ocaml indent 的变体 我能得到的最接近的结果是使用 Omlet vim 并一次缩进一行代码 在插入模式
  • 如何重构“字符串类型”代码?

    我目前正在开发一个代码库 其中有几类变量 例如数据库路径 它们简单地表示为字符串 这些 非 类型的大多数操作都在实用程序类中定义 我创建了一个新类来表示数据库 并将操作定义为实例方法 采用传统的 OOP 风格 然而 浏览大型代码库并重构它以
  • 具有特定深度的 TypeScript 递归类型

    TypeScript 允许您编写递归类型 但无法深入了解代码在较低级别 即深度 中如何变化 例如 下面的代码在所有级别上都具有相同类型的签名 并且我们必须在每个级别手动检查是否存在sub财产 type Recurse foo string
  • 如何使用 opam 安装特定版本的 ocaml 编译器

    如何使用 opam 或其他包管理器 安装特定版本的 ocaml 编译器 和兼容包 我快速浏览了 opam 文档 但没有找到相关信息 我需要 ocaml 编译器 最好是本机代码编译器 来构建 unison 一个文件同步软件 我需要使用相同版本
  • 运营商部分应用

    如果我想在字符末尾添加一个空格以返回列表 如果我不传递任何参数 我将如何通过部分应用程序来完成此操作 还有类型是 space Char gt Char 由于使用 和 运算符出现 解析错误 我在末尾添加空格时遇到问题 到目前为止我所拥有的是
  • 要统一的类型变量出现在类型中

    我有一个函数可以从两个列表重建一棵树 我返回所有分支的列表 但收到一个我不明白的错误 但我认为这与返回类型有关 错误是这样的 Can t unify a with a list Type variable to be unified occ
  • Oracle BLOB 与 VARCHAR

    我需要在表的一列中存储一个 大 SQL 查询 我想使用BLOB场地 需要明确的是 我想存储查询 而不是其结果 最好使用什么 BLOB or a VARCHAR 或者也许还有别的什么 另一种选择是 CLOB 对于文本数据 使用 CLOB 比使
  • OCaml 3.12 中的一流模块:它们将使哪些事情变得更容易(或可能)?

    我听说 OCaml 3 12 中即将推出 一流模块 他们将提供什么优势 哪些孩子的事情会变得更容易 他们试图解决什么问题 一个简单的例子就足够了 这只是一个可能的应用程序 但一流的模块可以轻松地对存在类型进行编码 基本上是一个模块打包存在类
  • Haskell 中的异构多态性(正确方法)

    让一个模块来抽象Area操作 错误的定义 class Area someShapeType where area someShapeType gt Float module utilities sumAreas Area someShape
  • mysql 中 int(11) 列的大小是多少(以字节为单位)?

    柱子的尺寸是多少int 11 在mysql中以字节为单位 该列中可以存储的最大值 An INT无论指定什么长度 都将始终为 4 个字节 TINYINT 1 字节 8 位 SMALLINT 2 字节 16 位 MEDIUMINT 3 字节 2
  • 链接“let”语句时使用“and”还是“in”更好?

    我意识到这可能是一个愚蠢的问题 但是 如果我把一堆let不需要需要了解彼此价值观的语句 使用是否更好and or in 例如 以下哪一个更可取 如果有 let a foo and b bar and c baz in etc or let
  • 防止被 0 除的 Typescript 类型

    我正在使用打字稿创建一个用于培训目的的计算系统 但在除法过程中出现打字错误 您知道如何解决吗 type Variable value number resolve gt number type NoZeroVariable value Om
  • 类 GADT 类型变量的未来角色?

    A 昨天的问题 https stackoverflow com q 41135212 3072788有一个定义HList 来自HList https hackage haskell org package HList 0 4 1 0 doc

随机推荐

  • 如何阅读/改进 PHP 计算的 C.R.A.P 指数

    我刚刚开始使用 PHPUnit 及其丰富多彩的代码覆盖率报告 我了解所有的数字和百分比 除了一个 C R A P 指数 谁能给我一个可靠的解释 解释它的含义 如何分析它以及如何降低它 Toader Mihai 提供了可靠的解释 https
  • 如何使用 docker-compose 重启单个容器

    我有一个docker compose yml包含 4 个容器的文件 redis postgres api and worker 在开发过程中worker容器 我经常需要重新启动它才能应用更改 有什么好的方法可以重新启动单个容器 例如work
  • 如何检查一个字符是否等于一个空格?

    这是我所得到的 private static int countNumChars String s for char c s toCharArray if Equals c 但该代码表示 找不到该方法的符号 我记得 Java 有一个这样的比
  • 基本路径覆盖有什么意义?

    文章位于onjava http www onjava com pub a onjava 2007 03 02 statement branch and path coverage testing in java html page 2似乎意
  • 无法在 Win 7 Prof 上以 64 位模式运行 CMD

    我已经完成了我的作业 诚实地尝试了我能想到的一切 但似乎每次我打开 CMD 时 我都会得到 32 位版本 无论我从哪里打开它 我努力了 Windows 启动 orb gt CMD gt 输入 输入 C Windows System32 cm
  • 尝试启动 TunnelProvider 网络扩展时出现 NEVPNErrorDomain 错误 1

    我正在尝试通过从 TunnelProvider 的 XCode 模板开始 然后将代码添加到主机应用程序来配置并启动它来制作自定义 TunnelProvider 网络扩展 我正在使用 NETunnelProviderManager 的实例来配
  • 如何使用冒泡排序在 Python 3 中对列表进行排序和子排序

    我正在为我正在学习的课程解答一个额外问题 假设我们有一个列表 例如mylist a1 b2 a3 c1 b1 a5 b3 c9 我想使用基本的Python而不导入任何东西 我想首先按字母顺序对列表进行排序 然后对于每个字母 我按数字排序 因
  • 拖放到桌面图标上

    我想这应该很简单 我在这里看过类似的问题 但我的旧大脑并不清楚它应该如何工作 我有一个 Windows 窗体应用程序 我的用户想要将文件拖到桌面上的应用程序图标上 并使用该文件执行程序 所以我想做的是 接受图标上放置的文件 启动应用程序并将
  • App Engine 从 JsonProperty 返回 JSON

    我喜欢如何JsonProperty当属性放入数据存储时 自动将 Python 结构编码为 JSON 并在检索时自动解码 但是 最好将该 JSON 数据发送到 Web 浏览器 而无需再次对其进行编码 有没有办法获取原始 JSON 数据 即阻止
  • 线程本地存储开销

    假设有一些不可重入函数使用全局变量 int i void foo void modify i 然后 我想在多线程代码中使用这个函数 所以我可以这样更改代码 void foo int i modify i 或者 通过使用 gcc thread
  • Java Swing - Repaint() 无法正常工作

    我从以下位置获取程序这个话题 https stackoverflow com questions 8693342 drawing a simple line graph in java 我尝试在实时模式下编辑点 我将 MouseMotion
  • API 和 ABI 之间的区别

    我是 Linux 系统编程新手 在阅读时遇到了 API 和 ABILinux系统编程 API定义 API 定义了接口 通过这些接口 一个软件可以进行通信 与源级别的另一个 ABI的定义 而 API 定义了源 接口 ABI 定义了 两者之间的
  • Xpath 选择包含特定列表子集的元素

    再会 假设以下 XML
  • “ps aux”有效,但“ps -aux”无效

    这似乎是一个愚蠢的问题 但我一直无法找到明确的答案 这个网站 http www linfo org ps html表明破折号是可选的 ps aux 然而 ps aux有效但是ps aux引发错误no user named x 有什么想法可能
  • 无法解析方法“registerForActivityResult”

    我正在构建一个自定义电容器插件来获取用户的电话号码 我将电容器 3 与 Ionic 6 一起使用 我找到了一个未被弃用的解决方案 并且是最近才获取用户的电话号码 这是我获取电话号码的代码 private void requestHint H
  • Chrome在浏览器后退按钮上再次执行所有JS

    我正在开发一个网络应用程序 我编写了一些 JS 脚本 以便在文档就绪时执行 但是在 Chrome 中 当我们单击后退按钮并返回到上一页时 它会再次执行所有 js 脚本 但是当我在 Firefox 上使用相同的方法时 它不会执行 JS 我在页
  • R 中的子列表命名

    假设我有一个包含 3 个子列表的列表 每个子列表携带 3 个数据帧 它看起来像这样 数据在最后 然后假设我有 2 个向量 j lt seq 10 20 length out 3 v lt seq 0 1 length out 3 我想创建一
  • 我应该将 Visual Studio 调试器附加到哪个进程来调试 Kestrel 应用程序?

    我正在启动命令行并使用运行我的应用程序dotnet run命令 这将启动 Kestrel 并显示我的应用程序 我应该如何确定要附加调试器的进程 以便可以调试 Kestrel 现在托管的网站 我特别需要能够这样做 这意味着我不能使用标准 F5
  • 如何在 Selenium 中结合隐式和显式超时?

    我正在使用带有隐式超时的 Selenium ChromeDriver driver Manage Timeouts ImplicitWait TimeSpan FromSeconds 5 在我的一项测试中 我想用明确的超时来覆盖它 在读取属
  • 类型变量和局部抽象类型有什么区别?

    我试图理解的目的局部抽象类型在 OCaml 中 局部抽象类型与类型变量有何不同 看来他们有相同的行为 Type variable let f x a a x val f a gt a